
accumulateParentOffsets=function (targetElement) {  
    let currentElement = targetElement;  
    let totalLeft = 0;  
    let totalTop = 0;  
  
    while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {  
        const computedStyle = window.getComputedStyle(currentElement);  
          
        if (computedStyle.position === 'relative') {  
            // 注意：offsetLeft 和 offsetTop 给出的是相对于最近的定位祖先的偏移  
            // 在这里，我们假设没有其他的定位祖先（或它们不影响我们的计算）  
            // 因为我们只关心 relative 定位的父元素  
            totalLeft += currentElement.offsetLeft;  
            totalTop += currentElement.offsetTop;  
        }  
  
        currentElement = currentElement.parentElement;  
    }  
  
    return { left: totalLeft, top: totalTop };  
}
function addcallback() {  
      let _this=this;

      //响应字典
      _this.callback_dct={}
      //触发响应函数
      _this.set=function(val){
        for(let key in _this.callback_dct){
            let item=_this.callback_dct[key];
            try{
                if(val==key){
                    if (item.__this__[item.set_name]==false){
                        item.__this__[item.set_name]=true;
                    }
                }else{
                    if (item.__this__[item.set_name]==true){
                        item.__this__[item.set_name]=false;
                    }
                }


            }
            catch{}
        }
      }
      //添加响应对象
      _this.add=function(obj){
        let key=obj.key;
        let set_name=obj.set_name;
        let __this__=obj.__this__;
        _this.callback_dct[key]={__this__:__this__,set_name:set_name};
      }
  }
// let addcallback_obj=new addcallback();
// addcallback_obj.add({'key':1,"__this__":'','set_name':"show_flag"})
// addcallback_obj.set("ddd")

//鼠标操作交互类
function a_move_class(){

    let _this=this;
    _this.regist_data={};//注册的数据
  
    _this.move_funcs={};//存放要执行的move函数的对象
    _this.up_funcs={};//存放要执行的up函数的对象
    _this.enter_funcs={};//存放要执行的enter函数的对象
    _this.leave_funcs={};//存放要执行的leave函数的对象
    _this.down_funcs={};//存放要执行的leave函数的对象
    _this.move_keys={};
    _this.keys={};//存放状态的对象
  
    _this.datas={};//存放用于传入各种函数的 一些数据参数
  
  
    //设置要运行的函数附带的参数
    _this.set_data=function(obj){
      let key=obj.key;
      let data=obj.data||{};
      // if(!_this.datas[key]){_this.datas[key]={}}
      _this.datas[key]=data;
    }
    _this.get_data=function(obj){
        let key=obj.key;
        return _this.datas[key];
    }
    //设置状态
    _this.set_flag=function(obj){
      let key=obj.key;
      let flag=obj.flag||true;
      _this.keys[key]=flag;
    }
    _this.set_move=function(obj){
    _this.move_funcs[obj.key]=obj.func;
    }
    _this.unset_move=function(obj){
        delete _this.move_funcs[obj.key];
    }
    _this.set_up=function(obj){
    _this.up_funcs[obj.key]=obj.func;
    }
    _this.unset_up=function(obj){
        delete _this.up_funcs[obj.key];
    }
    _this.set_enter=function(obj){
      let key=obj.key;
      let func=obj.func;
      let key2=obj.key2||'0';
      if(!_this.enter_funcs[key]){_this.enter_funcs[key]={}}
      _this.enter_funcs[key][key2]=func;
      // console.log("set_enter",obj)
    }
    _this.set_down=function(obj){
      let key=obj.key;
      let func=obj.func;
      let key2=obj.key2||'0';
      if(!_this.down_funcs[key]){_this.down_funcs[key]={}}
      _this.down_funcs[key][key2]=func;
      // console.log("down",obj)
    }
    _this.set_leave=function(obj){
      let key=obj.key;
      let func=obj.func;
      let key2=obj.key2||'0';
      if(!_this.leave_funcs[key]){_this.leave_funcs[key]={}}
      _this.leave_funcs[key][key2]=func;
    }
    // //鼠标释放触发函数
    // _this.mouseenter=function(event,params){
    //   for(let key in _this.regist_data){
    //     let obj=_this.regist_data[key];
    //     if(obj.mouseenter_flag==true){
    //       obj.mouseenter(event,params);
    //     }
    //   }
    // }
    //鼠标离开 触发函数
    _this.mousedown=function(event,params){
        for(let key in _this.keys){
          if(_this.keys[key]==true &&_this.leave_funs[key]){
            for(let k2 in _this.down_funcs[key]){
              try{
                _this.down_funcs[key][k2]({event:event,params:params,data:_this.datas[key]||{}})
              }
              catch{}
            }
          }
        }
    
      }
      
    //鼠标按下 触发函数
    _this.mouseup=function(event){
        // console.log("a_move_class up",_this.up_funcs)
        for (let key in _this.up_funcs){
            try{
                _this.up_funcs[key](event)
            }catch{}
        }
    }
    //鼠标移动 触发函数
    _this.mousemove=function(event){
        for (let key in _this.move_funcs){
            try{
                _this.move_funcs[key](event)
            }catch{}
        }
  
    }
    //鼠标移入 触发函数
    _this.mouseenter=function(event,params){
      for(let key in _this.keys){
        if(_this.keys[key]==true &&_this.enter_funs[key]){
          for(let k2 in _this.enter_funcs[key]){
            try{
              _this.enter_funcs[key][k2]({event:event,params:params,data:_this.datas[key]||{}})
            }
            catch{}
          }
        }
      }
  
    }
    //鼠标离开 触发函数
    _this.mouseleave=function(event,params){
      for(let key in _this.keys){
        if(_this.keys[key]==true &&_this.leave_funs[key]){
          for(let k2 in _this.leave_funcs[key]){
            try{
              _this.leave_funcs[key][k2]({event:event,params:params,data:_this.datas[key]||{}})
            }
            catch{}
          }
        }
      }
  
    }
    
    document.addEventListener('mousedown', _this.mousedown);  
    document.addEventListener('mousemove', _this.mousemove);  
    document.addEventListener('mouseup', _this.mouseup);  
    document.addEventListener('mouseleave', _this.mouseleave); // 注意是 mouseleave 而不是 mouseleve  
    document.addEventListener('mouseenter', _this.mouseenter);  
    }
function cookie_clear(key)                                                                            {
  document.cookie = key + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'                         ;}
function cookie_read(key)                                                                             {
  // 获取cookie字符串
  var cookieStr = document.cookie                                                                     ;
  // 拆分cookie字符串，得到键值对数组
  var cookieArr = cookieStr.split(";")                                                                ;
  // 遍历数组，查找指定键的cookie
  for(var i = 0; i < cookieArr.length; i++)                                                           {
    var cookiePair = cookieArr[i].split("=")                                                          ;
    if (cookiePair[0].trim() === key)                                                                 {
      // 找到指定键的cookie，返回其值
      return decodeURIComponent(cookiePair[1])                                                        ;}}
  // 未找到指定键的cookie，返回null
  return null                                                                                         ;}
function cookie_write(key, value, days=30)                                                            {
  // 设置cookie，有效期为指定天数之后的当前时间
  var expiryDate = new Date()                                                                         ;
  expiryDate.setDate(expiryDate.getDate() + days)                                                     ;
  document.cookie = key + "=" + encodeURIComponent(value) + "; expires=" + expiryDate.toUTCString()   ;}


  
function copy_text(text) {
    // Step 1: Check if the DOM element with id 'clipboard-container' exists
    let clipboardContainer = document.getElementById('clipboard-container');
    console.log("clipboardContainer",clipboardContainer)
    if (!clipboardContainer) {
        // If not, create a hidden div and append it to the body
        const newDiv = document.createElement('textarea');
        newDiv.id = 'clipboard-container';
        newDiv.style.position = 'absolute';
        newDiv.style.left = '-9999px';
        document.body.appendChild(newDiv);
        clipboardContainer = document.getElementById('clipboard-container');
    }
    clipboardContainer.value = text;
    
    clipboardContainer.focus();
    clipboardContainer.select();
   document.execCommand('copy');

}
window.get_max_key= function(dct){
    if (Object.keys(dct).length<1){return 0}
    return Object.keys(dct).reduce((max, current) => Math.max(max, current), -Infinity)}
window.get_time_x1=function(date_obj){
    return date_obj.getFullYear() + '-' + (date_obj.getMonth() + 1) + '-' + date_obj.getDate() + ' ' + date_obj.getHours() + ':' + date_obj.getMinutes() + ':' + date_obj.getSeconds();  
}

function get_url_params() {  
    // 创建一个URL对象  
    const urlObj = new URL(window.location.href);  
      
    // 使用URLSearchParams来解析查询字符串  
    const params = new URLSearchParams(urlObj.search);  
      
    // 初始化一个空对象来存储结果  
    let result = {};  
      
    // 遍历查询参数  
    for (let [key, value] of params.entries()) {  
        // 将查询参数添加到结果对象中  
        result[key] = value;  
    }  
      
    // 返回结果对象  
    return result;  
}
__get__obj=function(text,set_lst=[['font','0.9em helvetica']],set_class=""){
// 检查 ID 为 'xxx' 的元素是否存在  
let element = document.getElementById('get_w_____id');  
// 如果元素不存在，则创建并添加它  
if (!element) {  
    // 创建一个新的元素
    element = document.createElement('span');  
    // 设置新元素的 ID  
    element.id = 'get_w_____id';  
    // 添加到 body 的末尾  
    document.body.appendChild(element);  
} 
element.removeAttribute('style');
element.style.position = 'absolute'; // 避免影响页面布局  
element.style.visibility = 'hidden'; // 隐藏元素  
//设置class
document.className = set_class;  
try{
//设置style
for (let i=0;i<set_lst.length;i++){
    let item=set_lst[i];
    try{
        element.style[item[0]]=item[1];

    }catch{
        console.log("计算出错",item);
    }
}
}
catch{}
// 将文本添加到span中  
element.textContent = text;  
    return element;  
}


get_w=function(obj){
    let text=obj.text;
    let set_lst=obj.set_lst||[];
    let set_class=obj.set_class||'';
    return __get__obj(text,set_lst,set_class).offsetWidth;
}
get_h=function(obj){
    let text=obj.text;
    let set_lst=obj.set_lst||[];
    let set_class=obj.set_class||'';
    return __get__obj(text,set_lst,set_class).offsetHeight;
}
get_w2=function(obj){
    let _this=obj._this;
    let ref=obj.ref;
    // console.log("ref", _this.$refs[ref])
    return _this.$refs[ref].offsetWidth;
}
// get_w({text:"提示字符",set_class:"a_1_0_3_0_0_sub_menu_item"})
// window.get_xys=function (targetElement) {  
//     let currentElement = targetElement;  
//     let totalLeft = 0;  
//     let totalTop = 0;  
  
//     while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {  
//         let computedStyle = window.getComputedStyle(currentElement);  
          
//         if (computedStyle.position === 'relative') {  
//             // 注意：offsetLeft 和 offsetTop 给出的是相对于最近的定位祖先的偏移  
//             // 在这里，我们假设没有其他的定位祖先（或它们不影响我们的计算）  
//             // 因为我们只关心 relative 定位的父元素  
//             totalLeft += currentElement.offsetLeft;  
//             totalTop += currentElement.offsetTop;  
//         }  
  
//         currentElement = currentElement.parentElement;  
//     }  
//     let rect = targetElement.getBoundingClientRect();

//     let width = rect.width;
    
//     let height = rect.height;
//     return { left: totalLeft, top: totalTop,width:width,height:height};  
// }
window.lhp_check_obj=function(obj,key_name,data,console_=false){
    
    if(console_){try{console.log(obj.var_name);
}catch{}}
    if(console_){console.log("######################lhp_check_obj obj,key_name,data",obj,key_name,data,);
}
    // console.log("lhp_check_obj",obj,key_name,run_func,obj.hasOwnProperty(key_name))
    if(console_){console.log("######################lhp_check_obj 1");
}
    if(key_name==''){return null}
    if(console_){console.log("######################lhp_check_obj 2");
}
    if (obj.hasOwnProperty(key_name) && data!=obj[key_name]){
        console.log("拥有相同属性",obj,key_name);
        obj[key_name]=data;
    }else{
        if(console_){console.log("######################set  obj[key_name]=data",{"obj":obj,key_name:key_name,"data":data});
}
        obj[key_name]=data;
      }
    if(console_){console.log("######################lhp_check_obj 3");
}
}
window.lhp_copy1=function(a,__b){
    for(let key in __b){
        a[key]=b[key]
    }
}
//拷贝对象__b中的属性 到a中， 覆盖相同的属性
window.lhp_deepcopy1=function(a,__b){
    if (typeof __b !== 'object' || __b === null) {  
        return ;  
    }  
    let stack=[]
    for (let key in __b){
        stack.push([[key],__b[key]])
    }
    while( stack.length){
        let new_stack=[]
        for (let i =0;i<stack.length;i++){
            let item=stack[i]
            let key=item[0],value=item[1]
            let temp_val=a
            let temp_b=__b
            for(let j =0;j<key.length-1;j++){temp_val=temp_val[key[j]]}
            for(let j =0;j<key.length;j++){temp_b=temp_b[key[j]]}
            //如果a 拥有b这个属性 判断是否为对象，从而进行深度遍历
            // console.log(temp_val,key[key.length-1],key,a)
            if (key[key.length-1] in temp_val){
                //为对象 则加入深度遍历队列 等待下一轮遍历
                if(typeof temp_b === 'object' && temp_val[key[key.length-1]]!=null){for (let k in temp_b){new_stack.push([ [...key, k],temp_b[k]])}}
                //不为对象  则直接覆盖
                else{
                // console.log('不拥有直接覆盖',key,temp_b)
                    temp_val[key[key.length-1]]=temp_b}
            }
            //不拥有 则直接覆盖
            else{
                // console.log('不拥有直接覆盖',key,temp_b)
                //如果是数组 则直接插入
                if (Array.isArray(temp_val)){
                    temp_val.push(temp_b)
                }else{
                //不是数组 就按照对象设置属性
                    temp_val[key[key.length-1]]=temp_b
                }
                
            }
            
        }
        stack=new_stack
    }

}
// a={"aa":{1:1}}
// b={"aa":{1:"null"}}
// lhp_deepcopy1(a,b)
// console.log(a)
// a=null;
// a={1:{3:4,1:2,e:{f:{l:{h:[3],x:[1,2,3]}},zz:22,pp:66}}},b={1:{1:3,5:6,e:{f:{l:{h:[1,2,3]}}}},2:4,d:undefined}

// lhp_deepcopy1(a,b)
// c={
//     "1": {
//         "1": 3,
//         "3": 4,
//         "5": 6,
//         "e": {
//             "f": {
//                 "l": {
//                     "h": [
//                         1,
//                         2,
//                         3
//                     ],
//                     "x": [
//                         1,
//                         2,
//                         3
//                     ]
//                 }
//             },
//             "zz": 22,
//             "pp": 66
//         }
//     },
//     "2": 4
// }
// console.log(a) 


// a={callback:null}
// b={callback:function(){console.log('zzz')}}
// lhp_deepcopy1(a,b)
// console.log("a:",a)
//拷贝对象__b中的属性 到a中， 覆盖相同的属性

window.lhp_deepcopy2=function(a,path,__b){
    if (typeof __b !== 'object' || __b === null ||path=='') {  
      //   console.log("???")
        return ;  
    }  
    __b=JSON.parse(JSON.stringify(__b));
    let path_lst=path.split(".");
    for(let i=0;i<path_lst.length-1;i++){a=a[path_lst[i]]}
    let stack=[]
    stack.push([[],__b])
   //  console.log("stack:",stack)
    while( stack.length){
        let new_stack=[]
        for (let i =0;i<stack.length;i++){
            let item=stack[i]
            let key=item[0],value=item[1]
            let temp_val=a
            let temp_b=__b
            if (key.length==0){
                let kkpath=path_lst[path_lst.length-1];
                if (kkpath in temp_val){
                    //为对象 则加入深度遍历队列 等待下一轮遍历
                    if(typeof temp_b === 'object'&&temp_b!=null&& temp_val[kkpath]!=null){for (
                     let k in temp_b){new_stack.push([ [...key, k],temp_b[k]])}}
                    //不为对象  则直接覆盖
                    else{
                  //   console.log('不拥有直接覆盖1',key,temp_b)
                        temp_val[kkpath]=temp_b}
                }
                //不拥有 则直接覆盖
                else{
                  //   console.log('不拥有直接覆盖2',key,temp_b)
                    //如果是数组 则直接插入
                    if (Array.isArray(temp_val)){
                        temp_val.push(temp_b)
                    }else{
                    //不是数组 就按照对象设置属性
                        temp_val[kkpath]=temp_b
                    }
                    
                }
            break}
            temp_val=temp_val[path_lst[path_lst.length-1]]
            for(let j =0;j<key.length;j++){temp_b=temp_b[key[j]]}
            for(let j =0;j<key.length-1;j++){temp_val=temp_val[key[j]]}
            
            //如果a 拥有b这个属性 判断是否为对象，从而进行深度遍历
            if (key[key.length-1] in temp_val){
               //  console.log("如果a拥有b这个属性",key[key.length-1])
                //为对象 则加入深度遍历队列 等待下一轮遍历
                if(typeof temp_b === 'object' &&temp_b !=null && temp_val[key[key.length-1]]!=null){
                  
                  // console.log("????")
                  for (let k in temp_b){
                    new_stack.push([ [...key, k],temp_b[k]])}}
                //不为对象  则直接覆盖
                else{
               //  console.log('不拥有直接覆盖3',key,temp_b)
                    temp_val[key[key.length-1]]=temp_b}
            }
            //不拥有 则直接覆盖
            else{
               //  console.log('不拥有直接覆盖4',key,temp_b)
                //如果是数组 则直接插入
                if (Array.isArray(temp_val)){
                    temp_val.push(temp_b)
                }else{
                //不是数组 就按照对象设置属性
                    temp_val[key[key.length-1]]=temp_b
                }
                
            }
            
        }
        stack=new_stack
    }

}
window.lhp_delete2=function(a,path){
    if (path=='') {  return ;     }  
    let path_lst=path.split(".");
    let last_idx=path_lst.length-1;
    for(let i=0;i<last_idx;i++){a=a[path_lst[i]]}
    delete a[path_lst[last_idx]]

}
// let a={1:{3:4,1:2,c:{}}},path="1.c.z",b={1:{1:3,5:6},2:4,d:undefined}
// lhp_deepcopy2(a,path,b)
// console.log("a:",a)

// a=[0,0,2,3,[1,2,3]],path="4.3",b=[1,2,3,4,[1,2,3,4,5]]
// lhp_deepcopy2(a,path,b)
// console.log("a:",a)

window.lhp_loop_time2=100
window.lhp_loop_time_funcs2={}
window.lhp_loop_time_obj2=null
window.lhp_loop_time_func2=function(){
  clearTimeout(lhp_loop_time_obj2);//清除定时器
  for (let key in lhp_loop_time_funcs){
    let item=lhp_loop_time_funcs[key];
    if (item.now_time==null){item.now_time=0;}
    if (item.now_time>item.time){
      item.now_time=0;
      item.func()
    }else{item.now_time++}
  }
  lhp_loop_time_obj2 = setTimeout(lhp_loop_time_func2, 1000); //设定定时器，循环运行
}
lhp_loop_time_obj2 = setTimeout(lhp_loop_time_func2, 1000); //开始运行
window.lhp_loop_time_func2_add=function(obj){}
// let lhp_loop_time_funcs___test_func=function(){console.log('test')}
// let lhp_loop_time_funcs___test={
//   'key':{'time':2,//两秒执行一次
//           'func':lhp_loop_time_funcs___test_func
//         },
// }
// window.lhp_loop_time_funcs=lhp_loop_time_funcs___test
window.lhp_run_func_check=function(str_){
    if (str_==''){return true;}
    else if (str_.includes('.')){
        let arr = str_.split('.');  
        let run_func=window
        try{for (let i=0;i<arr.length;i++){ run_func=run_func[arr[i]]}}
        catch{return false}
  
        if (run_func!=undefined && run_func!=null){
            return true
        }else{
            return false
        }
  }
  }
window.lhp_run_func=function(str_,obj=null,test=false){
    if ((typeof str_) ==='function'){
        if (obj!=null){
            return str_(obj)
        }else{
            return str_()
        }
    }
    try{
        if (str_==''){return null;}
        else if (str_.includes('.')){
            let arr = str_.split('.');  
            let run_func=window
            for (let i=0;i<arr.length-1;i++){ run_func=run_func[arr[i]]}
            if (obj!=null){
                if(test){console.log("lhp_run_func func params:",run_func[arr[arr.length-1]],obj)
}
                return run_func[arr[arr.length-1]](obj)
            }else{
                return run_func[arr[arr.length-1]]()
            }
        }else{
            if (obj!=null){
                return window[str_](obj)
            }else{
                return window[str_]()
            }
        }
        
  }catch(err){if(test){console.log("lhp_run_func err:",err);
}}
}

async function lhp_run_func2_run_func(fn,obj=null) {
    if (fn.constructor.name === 'AsyncFunction') {
        // 如果是 async 函数，使用 await
        if(obj!=null){
            return await fn(obj);

        }else{
            return await fn();
        }
    } else {
        // 如果是普通函数，直接调用
        if(obj!=null){
            return fn(obj);

        }else{
            return fn();
        }
    }
}
window.lhp_run_func2=async function(str_,obj=null,test=false){
    if ((typeof str_) ==='function'){
        await lhp_run_func2_run_func(str_,obj);
    }
    try{
        if (str_==''){return null;}
        else if (str_.includes('.')){
            let arr = str_.split('.');  
            let run_func=window
            for (let i=0;i<arr.length-1;i++){ run_func=run_func[arr[i]]}
            await lhp_run_func2_run_func(run_func[arr[arr.length-1]],obj);
        }else{
            await lhp_run_func2_run_func(window[str_],obj);
        }
        
  }catch(err){if(test){console.log("lhp_run_func err:",err);
}}
}
window.lhp_vue_set=function(obj_
    ){
        let data_type=obj_.data_type;//要修改的数据类型  post||put delete clear
        let _this=obj_._this;//this vue对象
        let path=obj_.path;//path为data_obj要修改的数据的路径
        let data=obj_.data;//data为修改的数据
    //类型为新增或者修改
    if (data_type=='postput'){
    let change_obj=_this.data;
    let last_path=null;
    if (path.indexOf(".") !== -1){
        let path_lst=path.split(".");
        for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
        last_path=path_lst[path_lst.length-1];
    }else{last_path=path}
    // console.log("path",path)
    // console.log("_this.$set(change_obj,last_path,data)",change_obj,last_path,data)
    _this.$set(change_obj,last_path,JSON.parse(JSON.stringify(data)))
    //类型为删除
    }else if(data_type=="delete"){
        let change_obj=_this.data;
        let father_idx=null;
        let father_obj=null;
        if (path.indexOf(".") !== -1){
            let path_lst=path.split(".");
            if (path_lst.length<=1){console.log("delete异常 数量小于等于1");
return}
            for (let i=0;i<path_lst.length-1;i++){father_obj=change_obj;father_idx=path_lst[i];change_obj=change_obj[path_lst[i]];}
            let last_idx=path_lst[path_lst.length-1];
            let new_data=JSON.parse(JSON.stringify(change_obj));
            if(typeof new_data =="object") {  
                if (Array.isArray(new_data)){
                    new_data.splice(last_idx,1);

                }else{
                    delete new_data[last_idx]
                }
            _this.$set(father_obj,father_idx,new_data)
        }}else{console.log("delete异常 数量小于2");
return}

        
//类型为清空数据
}else if(data_type=="clear"){
    let change_obj=_this.data;
    let last_key=null;
    if (path.indexOf(".") !== -1){
        let path_lst=path.split(".");
        for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
        last_key=path_lst[path_lst.length-1];
    }else{
        last_key=path;
    
    }
    let temp_val=change_obj[last_key]
switch (typeof temp_val) {  
        case 'object':  
            // 注意：这里会匹配到null，因为null也是object类型  
            // 需要额外检查是否为null  
            if (temp_val === null) {  
                change_obj[last_key] = null; // 或者你可以将null也设置为{}  
            } else if (Array.isArray(temp_val)) {  
                change_obj[last_key] = [];  
            } else {  
                change_obj[last_key] = {};  
            }  
            break;  
        case 'string':  
        change_obj[last_key] = '';  
            break;  
        case 'number':  
        change_obj[last_key] = 0;  
            break;  
        case 'boolean':  
        change_obj[last_key] = false;  
            break;  

}


}else if(data_type=='insert'){
    // let before_idx=obj_.before_idx;
    let change_obj=_this.data;
    // let last_path=null;
    // console.log("insert检查-1 obj_",obj_)
    // console.log("insert检查 前data",JSON.parse(JSON.stringify(_this.data.data)))
    if (path.indexOf(".") !== -1){
        let path_lst=path.split(".");
        for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
        last_path=path_lst[path_lst.length-1];
    }else{last_path=path}
    // let new_val=JSON.parse(JSON.stringify(change_obj[last_path]));
    
    // if (before_idx===null || (!(before_idx===undefined))){
    //     new_val.push(JSON.parse(JSON.stringify(obj_.copy_data)));
    // }else{
    //     new_val.splice(before_idx,0,JSON.parse(JSON.stringify(obj_.copy_data))); 
    // }
    console.log("insert检查 path",path)
    console.log("insert检查 change_obj,last_path,new_val",change_obj,last_path)
    _this.$set(change_obj,last_path,JSON.parse(JSON.stringify(data)))
    console.log("insert检查 后data",JSON.parse(JSON.stringify(_this.data)))
    //类型为删除
    }
}


// aaa={
//     "htmlcrud": {},
//     "table_base_info": {
//         "备注": "这是用于存储一些加工罐数据信息的数据库",
//         "名称": "添加测试的库2"
//     },
//     "table_field_info": {
//         "create_people_id": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "创建人id",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "用于记录这条数据的创建人，方便追溯"
//         },
//         "create_time": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "创建时间",
//             "字段类型": "DATETIME",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "用于记录这条数据的创建时间，方便追溯"
//         },
//         "device": {
//             "edit_lhp_text": true,
//             "htmlcrud": {},
//             "show_lhp_text": "{}",
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": true,
//             "前端是否显示": true,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "",
//             "名称": "加工罐设备号",
//             "字段类型": "VARCHAR",
//             "字段长度": [
//                 0,
//                 20
//             ],
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "加工罐设备号 如PP01"
//         },
//         "hidden": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": null,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "",
//             "名称": "是否隐藏",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "删除的数据和修改的数据会被隐藏，但是追溯时可以查询"
//         },
//         "html_type": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "名称": "前端的显示状态",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": "",
//             "备注": "前端的显示状态"
//         },
//         "id": {
//             "htmlcrud": {},
//             "主键": true,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "加工罐id",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": null,
//             "自增长": true,
//             "自定义_默认值": null,
//             "备注": "唯一id方便增删改查"
//         },
//         "level": {
//             "edit_lhp_text": true,
//             "htmlcrud": {},
//             "show_lhp_line": "{\"h_size\":0.16,\"w_size\":1,\"number\":120,\"max\":2}",
//             "show_lhp_text": "{\"val\":1}",
//             "show_lhp_xtext": "m",
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": true,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "液位",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": "0",
//             "备注": "加工罐的液位"
//         },
//         "mode": {
//             "edit_lhp_text": true,
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "设备状态",
//             "字段类型": "TEXT",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": "",
//             "备注": "# 当前工作模式 0空闲模式 1自动运行 2单步运行 3调试运行"
//         },
//         "modify_count": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": null,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "",
//             "名称": "修改次数",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "记录修改次数，方便产品追溯。"
//         },
//         "modify_people_id": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "修改人id",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "用于记录这条数据的修改人，方便追溯"
//         },
//         "modify_time": {
//             "htmlcrud": {},
//             "update_modify_time": true,
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "修改时间",
//             "字段类型": "DATETIME",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "用于记录这条数据的修改时间，方便追溯"
//         },
//         "name": {
//             "edit_lhp_text": true,
//             "htmlcrud": {},
//             "show_lhp_text": "{}",
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": true,
//             "前端是否显示": true,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "加工罐名称",
//             "字段类型": "VARCHAR",
//             "字段长度": [
//                 0,
//                 20
//             ],
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "加工罐名称方便客户选择"
//         },
//         "notes": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": null,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "",
//             "名称": "备注",
//             "字段类型": "TEXT",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": "",
//             "备注": "记录这条数据需要注意的事项"
//         },
//         "pH": {
//             "edit_lhp_text": true,
//             "htmlcrud": {},
//             "show_lhp_line": "{\"h_size\":0.16,\"w_size\":1,\"number\":120,\"max\":10}",
//             "show_lhp_text": "{\"val\":1}",
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": true,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "PH",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": "0",
//             "备注": "加工罐的PH值"
//         },
//         "process": {
//             "edit_lhp_text": true,
//             "htmlcrud": {},
//             "show_lhp_number2text": "{\"0\":\"机械臂调配\",\"1\":\"装载花盘\",\"2\":\"进脱色液\",\"3\":\"脱色\",\"4\":\"排脱色液\",\"5\":\"清洗\",\"6\":\"加注色素\",\"7\":\"上色\",\"8\":\"排色素\",\"9\":\"出花\",\"10\":\"清洗管道\",\"11\":\"空闲\"}",
//             "show_text": true,
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": true,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "工艺步骤",
//             "字段类型": "TEXT",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": "",
//             "备注": "# 当前加工工艺的步骤id   0机械臂调配 1装载花盘2进脱色液3脱色4排脱色液 5清洗 6加注色素 7上色 8排色素 9出花 10清洗管道 11空闲"
//         },
//         "temp": {
//             "edit_lhp_text": true,
//             "htmlcrud": {},
//             "show_lhp_line": "{\"h_size\":0.16,\"w_size\":1,\"number\":120,\"max\":300}",
//             "show_lhp_text": "{\"val\":1}",
//             "show_lhp_xtext": "℃",
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": false,
//             "前端是否显示": true,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "温度",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": "0",
//             "备注": "加工罐的温度"
//         },
//         "use": {
//             "htmlcrud": {},
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": null,
//             "前端是否显示": false,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "",
//             "名称": "是否使用",
//             "字段类型": "INTEGER",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "自定义_默认值": null,
//             "备注": "用于记录这条数据的是否使用，方便追溯"
//         },
//         "variety_name": {
//             "edit_lhp_search_text_list": true,
//             "edit_lhp_search_text_list_head_data": "{\"db_name\":\"variety_db\",\"select_field\":[\"id\",\"name\"]}",
//             "edit_lhp_search_text_list_load_url": "/V1/db_handle",
//             "htmlcrud": {},
//             "show_lhp_text": true,
//             "主键": false,
//             "前端上传限制": null,
//             "前端上传限制提示": null,
//             "前端是否可以修改": true,
//             "前端是否显示": true,
//             "前端输入限制": null,
//             "前端输入限制提示": null,
//             "前端配置参数": "{\"width\": 120}",
//             "名称": "使用工艺",
//             "字段类型": "TEXT",
//             "字段长度": null,
//             "索引": true,
//             "自增长": null,
//             "备注": "加工罐的工艺队列 按照队列顺序进行加工"
//         }
//     }
// }
// 正在编辑的配置.更新函数({data_type:"postput",path:"db_config.ee2",data:aaa})
// 正在编辑的配置.更新函数({data_type:"delete",path:"db_config.ee2",})
// console.log("数据库列表:",数据库列表.data)
// 原生js 加载css
// 存储加载过的CSS URL
window.cssjssrc={
    loadedCSS :[],
    loadedScripts : []
    }
    
    // 动态加载CSS
    function loadCSS(url) {
    url = url.replace(/\\/g, '/');  
    url="http://" +  window.location.hostname + ":" + window.location.port + url;  
    // 检查URL是否已加载
    if (cssjssrc.loadedCSS.includes(url)) {
        // CSS已加载，无需重新加载
        return;
    }
    
    // 创建新的link元素并设置属性
    var link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.href = url;
    
    // 插入新的link元素到页面的头部
    document.getElementsByTagName('head')[0].appendChild(link);
    
    // 将URL添加到loadedCSS对象中
    cssjssrc.loadedCSS.push(url);
    }
                // // 使用该函数加载CSS
                // loadCSS('path/to/your.css');
    //原生js 加载js
            // 存储加载过的JavaScript URL
            // 动态加载JavaScript
    function loadScript(url) {
    
    url = url.replace(/\\/g, '/');  
    url="http://" +  window.location.hostname + ":" + window.location.port + url;  
    // console.log('#######',cssjssrc.loadedScripts)
    // console.log('#######',url)
    
    // 检查URL是否已加载
    if (cssjssrc.loadedScripts.includes(url)) {
        // JavaScript已加载，无需重新加载
        return;
    }
    
    // 创建新的script元素并设置属性
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    
    // 插入新的script元素到页面的尾部
    document.body.appendChild(script);
    
    // 将URL添加到loadedScripts对象中
    cssjssrc.loadedScripts.push(url);
    }
    function loadcssjs(url){
        if (url.endsWith('.js')){loadScript(url)}else{loadCSS(url)}
    }
    
function getLoadedResources() {  
    // 初始化 JavaScript src 数组  
    var jsSrcs = [];  
    // 初始化 CSS src 数组  
    var cssSrcs = [];  
    // 获取所有已加载的 script 元素  
    var scriptElements = document.querySelectorAll('script');  
    // 遍历所有已加载的 script 元素  
    for (var i = 0; i < scriptElements.length; i++) {  
      // 将 script 元素的 src 属性值添加到 JavaScript src 数组中  
      jsSrcs.push(scriptElements[i].src);  
    }  
    // 获取所有已加载的 link 元素，并筛选出 rel 属性为 stylesheet 的元素  
    var stylesheetElements = document.querySelectorAll('link[rel="stylesheet"]');  
    // 遍历所有已加载的 stylesheet 元素  
    for (var i = 0; i < stylesheetElements.length; i++) {  
      // 将 stylesheet 元素的 href 属性值添加到 CSS src 数组中  
      cssSrcs.push(stylesheetElements[i].href); 
    }  
    // 返回包含 JavaScript src 和 CSS src 的对象  
    return {  
      loadedScripts: jsSrcs,  
      loadedCSS: cssSrcs  
    };  
  }
  document.addEventListener('DOMContentLoaded', function() {  
  
    // DOM已完全加载和解析，现在可以执行需要的操作  
    window.cssjssrc=  getLoadedResources()
  
  });

function page_size_listen_class() {
    let _this=this;
    _this.objs={};//存放所有注册的数据 {"a":{"name":"布局1","change_name":"height","now":"35",val:"",change_func:func}}
    _this.objs2={};//存放所有关联的数据 {"布局1":{"change_name":"height",lst:["a"]}}
    _this.run_func=function(str_,obj=null,test=false){
        if ((typeof str_) ==='function'){
                return str_("calc("+obj+")");
        }
        try{
            if (str_==''){return null;}
            else if (str_.includes('.')){
                let arr = str_.split('.');  
                let run_func=window
                for (let i=0;i<arr.length-1;i++){ run_func=run_func[arr[i]]}
                run_func[arr[arr.length-1]]("calc("+obj+")");
            }else{
                return window[str_]("calc("+obj+")");
            }
            
      }catch(err){if(test){console.log("lhp_run_func err:",err);
    }}
    }
    _this.注册=function(obj){
        let key_name=obj.key_name;//注册的名称 唯一
        let name=obj.name;//注册的空间名称  如果同空间有数据变动，那么会调用同空间的其他数据的 change_func函数
        let change_name=obj.change_name;//注册的数据名称  height或者width
        let change_func=obj.change_func;//注册的调用函数  将数据同步到位 的函数
        let val=obj.val;//计算的值35px  【表示35px】100% - 35px 【100% - 35px】width - {a} - {b} 【表示浏览器值-布局中a占有的尺寸值 -布局中b占有的尺寸值】
        _this.objs[key_name]={
            key_name:key_name,
            change_name:change_name,
            change_func:change_func,
            name:name,
            val:val
        }
        if(_this.objs2[name]){
            _this.objs2[name].lst.push(key_name);
        }else{
            // console.log("不存在则新建",key_name,[key_name])
            let new_l=[key_name]
            _this.objs2[name]={lst:[key_name],change_name:change_name}
            // console.log("不存在则新建",key_name,_this.objs2[name])
        }
        _this.更新空间(name);
        let 更新函数=function(val){
            console.log("开始更新值",{key_name:key_name,val:val})
            _this.更新值({key_name:key_name,val:val});
        }
        return 更新函数
    }
    _this.eval=function(obj,val){
        while (val){
            let new_val=_this.替换值(val,obj);
            if(new_val==null){return val}
            else if(new_val==undefined){return undefined}
            else{
                val=new_val;
            }
        }
    }

    _this.替换值=function(inputStr,obj) {
        // Step 1: 获取字符串中第一个 '{' 字符的索引
        let openBracketIndex = inputStr.indexOf('{');
        // 检查是否找到了 '{'
        if (openBracketIndex === -1) {
          return null; // 或者你可以抛出一个错误
        }
        // Step 2: 获取字符串中第一个 '}' 字符的索引
        let closeBracketIndex = inputStr.indexOf('}');
        
        // Step 3: 根据 '{' 和 '}' 的索引，获取 '{' 到 '}' 中间的字符串，并保存到变量 xx 中
        let xx = inputStr.substring(openBracketIndex + 1, closeBracketIndex);
        if(obj[xx]==undefined){
            return undefined
        }
        // Step 4: 将从 '{' 到 '}' 的字符串替换为字符串 "rrrr"
        let resultStr = inputStr.slice(0, openBracketIndex) + '('+obj[xx]+')' + inputStr.slice(closeBracketIndex + 1);
        
        // 返回结果字符串和变量 xx（虽然 xx 是在函数内部使用的，但你可以根据需要返回它）
        return resultStr
      }
    _this.更新空间=function(name){try{
        console.log("开始更新值3",name)
        let set_val={};
        let lst=JSON.parse(JSON.stringify(_this.objs2[name].lst));
        let val_default={height:window.innerHeight+'px',width:window.innerWidth+'px'};
        console.log("开始更新值3-2",val_default)
        for(let i=0;i<lst.length;i++){
            val_default[lst[i]]=_this.objs[lst[i]].val;
        }
        for (let i=0;i<lst.length;i++){
            set_val[lst[i]]=undefined
        }
        console.log("开始更新值3-3",_this,lst)
        while (lst.length){
            let key_name=lst.shift();
            let val=_this.objs[key_name].val;
            console.log("更新空间3",_this,name)
            try{
                let new_val=_this.eval(val_default,val);
                if(new_val!=undefined){
                    set_val[key_name]=new_val;
                    console.log("运行",name,_this.objs2[name],key_name,new_val)
                    _this.run_func(_this.objs[key_name].change_func,new_val);
                }else{
                    lst.push(key_name);
                }

            }catch (err){
                
                console.log("更新空间err",_this,name,err)
            }

            
        }}catch (err){console.log("开始更新值3-2 err",err)}
    };
    _this.更新值=function(obj){
        let key_name=obj.key_name;
        let val=obj.val;
        _this.objs[key_name].val=val;
        console.log("开始更新值2",_this.objs[key_name].name)
        try{
        _this.更新空间(_this.objs[key_name].name)}catch (err){console.log("开始更新值2-2 err",err)}

    }
    _this.更新所有设置 = function(){
        for(let k in _this.objs2){
            _this.更新空间(k);
        }
    };  
    window.addEventListener('resize',_this.更新所有设置);  
}  
// page_size_listen_obj=new page_size_listen_class();
// 更新函数=page_size_listen_obj.注册({key_name:"容器上",name:"布局空间1",change_name:"height",change_func:'',val:'35'})
// page_size_listen_obj.更新所有设置()
function request______(js_obj){
  // console.log("js_obj",js_obj)
    //js_obj.method       请求格式是get 还是post  还是put  还是delete
    var method =js_obj.method;
    var onerror= js_obj.onerror!=null ? js_obj.onerror : function(){}
    var error_run_func=  js_obj.error_run_func!=null ? js_obj.error_run_func : function(){}
    var onnetworkerror= js_obj.onnetworkerror!=null ? js_obj.onnetworkerror : function(){}
    let url_ = js_obj.url;
    return function(js_obj2){
        //js_obj2.head_data    存放在url上的json数据
        //js_obj2.body_data    存放在body上的json数据
        //js_obj2.url          url
        let head_data=js_obj2.head_data;
        let body_data=js_obj2.body_data;
        // console.log('method:',method)
        // console.log('head_data:',head_data)
        // console.log('body_data:',body_data)
        // console.log(' ')
        let execute_lst=js_obj2.execute_lst;
        let url=url_;
        if (url==null){throw new Error('不能缺少url参数');}//缺少url就抛出异常
        if (head_data!=null){url=url+'?'+JSON.stringify(head_data)}//如果head_data不为空  就将head_data转为json格式存入url
        if (js_obj2.body_data!=null &&(method.toLowerCase()=='post' ||method.toLowerCase()=='put'  )){body_data=JSON.stringify(body_data)}else{body_data="{}"}//如果为post 或者 put 将body_data转为json格式
        let xhr = new XMLHttpRequest();
        xhr.open(method, url, true);
        xhr.onload = function() {
      if (xhr.status === 200) {
        // 请求成功，将返回的 JSON 数据解析为对象，并传递给回调函数
        // console.log('xhr.responseText',xhr.responseText)
        // console.log('typeof',typeof xhr.responseText,xhr.responseText)
        var received_data = JSON.parse(xhr.responseText);
        if (received_data.type=='error'){
          Vue.prototype.$notify({type: 'error',message: received_data.message||'错误'})
          console.log("dddd",error_run_func)
          error_run_func(received_data)
          return null
        }else if(received_data.type=='ok' || received_data.type=='success' ){
          // console.log("received_data.type 22",received_data)
          Vue.prototype.$notify({type: 'success',message: received_data.message||'操作成功'})
        }
        // console.log("received_data.type",received_data.type)
        if (execute_lst==null)execute_lst=[]
        for (let i=0;i<execute_lst.length;i++){
            let item=execute_lst[i];
            // console.log(`######execute_lst[${i}]`,execute_lst)
            
            if (item.type=='func'){//运行函数
              let temp_func=item.func//传递进来的函数
              if (temp_func==null)continue;
              let args=  item.args;     
              // console.log('###args1###',args)
              let kwargs=  item.kwargs;      
              if (args==null){args=[]}    
              if (kwargs==null){kwargs={}}
              // console.log('###args2###',args)
              // args=['44','44']
              // kwargs={'ww':44,'ee':33}
              // 我要将args=的数组索引和kwargs的属性 统一存入temp_idx数组中 temp_idx格式为[['args',0],['args',1],['kwargs','ww'],['kwargs','ee']]
              // 你可以使用JavaScript的Object.keys()和Array.prototype.map()方法来获取kwargs的键和args的索引
              let temp_idx =[]
              for (let eee=0;eee<args.length;eee++){
                temp_idx.push(['args', eee])
              }
              temp_idx=temp_idx.concat(Object.keys(kwargs).map(key => ['kwargs', key])); 
              // console.log('###args3###',args)
              for (let ii_args=0;ii_args<temp_idx.length;ii_args++){
                      let iitem=temp_idx[ii_args];//['args',1]  ['kwargs','ee']
                      let data___=null;
                      let temp_iitem=null
                      if (iitem[0]=='args'){temp_iitem=args[iitem[1]]}else{temp_iitem=kwargs[iitem[1]]}
                      // console.log('temp_iitem',temp_iitem)
                      // console.log('Array.isArray(temp_iitem)',Array.isArray(temp_iitem))
                      // console.log('temp_iitem',temp_iitem)
                      if (typeof temp_iitem === 'string'){
                        data___=received_data;           //获取变量地址
                        // console.log('str!!!',data___,received_data)
                        let temp_lst=temp_iitem.split('.');          //拆分数组
                        let last_name=temp_lst[temp_lst.length-1];//最后一个变量的名字
                        for (let ii=0;ii<temp_lst.length-1;ii++){data___=data___[temp_lst[ii]]}
                        data___=data___[last_name]
                        if (temp_iitem=='received_data')data___=received_data
                      }else if(Array.isArray(temp_iitem)){
                        
                        data___=temp_iitem[0];           //获取变量地址
                        // console.log('ddddd111',data___)
                        let temp_lst=temp_iitem[1].split('.');          //拆分数组
                        let last_name=temp_lst[temp_lst.length-1];//最后一个变量的名字
                        for (let ii=0;ii<temp_lst.length-1;ii++){data___=data___[temp_lst[ii]]}
                        // console.log('ddddd2222',data___,last_name)
                        data___=data___[last_name]
                      }
                      
                      //  console.log(  '###args5###',args)
                      //  console.log('iitem',iitem)
                      if (iitem[0]=='args'){args[iitem[1]]=data___}
                      else if (iitem[0]=='kwargs'){kwargs[iitem[1]]=data___}
                      
                      // console.log(  '###args6###',args)
                    }
              let args_str='';
              if (args.length!=0){
                // console.log('errrrrrr  args',args);
              args_str='args['+args.map((value, index) => index).join('],args[')+']';}
              let kwargs_str='';
              let kwargs_key_lst=Object.keys(kwargs).map(key => key);
              for (let fjsdlakfj=0;fjsdlakfj<kwargs_key_lst.length;fjsdlakfj++){
              kwargs_str=kwargs_str+','+kwargs_key_lst[fjsdlakfj]+'='+'kwargs['+kwargs_key_lst[fjsdlakfj]+']'
              }
              // console.log(args_str,kwargs_str);
              let tttemp_str='';
              if (args_str==''&&kwargs_str!=''){tttemp_str="temp_func("+kwargs_str.substring(1, str.length)+")"}
              else{tttemp_str="temp_func("+args_str+kwargs_str+")"}
              // console.log('###args4###',args)
              // console.log("%%%%%%%%",args[0])
                // console.log('args',args)
              // eval('console.log("%%%%%%%%",args[0])')
              // console.log('eval::::',tttemp_str)
              // console.log('item:',item)
              // console.log('item.args_',item.args_)
              if (item.args_!=null)tttemp_str="temp_func("+item.args_.map((item, index) => `item.args_[${index}]`).join(',')+")"
              if (item.kwargs_!=null){
                // console.log('kwargs_',item.kwargs);
              
              tttemp_str="temp_func("+Object.keys(item.kwargs_).map(x => x+'=item.kwargs_["'+x+'"]').join(',')+")"}
              // console.log('eval::::',tttemp_str)
              // console.log('temp_func',temp_func)
              if (args!=null){for (let iiis=0;iiis<args.length;iiis++){
                // console.log(`args[${iiis}]`,args[iiis])
              }}
               if (item.timesleep!=null)setTimeout(eval(tttemp_str),item.timesleep)//如果需要则延时执行
               else{eval(tttemp_str)}//不延时直接执行
  
            }
            else if (item.type=='set_val'){
              let val1=item.val1
              let val2=item.val2
              let data___1=null;
              let temp_lst1=[]
              let data___2=null;
              let temp_lst2=[]
              if (typeof val1 === 'string'){data___1=received_data;temp_lst1=val1.split('.')}else{data___1=val1[0];temp_lst1=val1[1].split('.')}
              if (typeof val2 === 'string'){data___2=received_data;temp_lst2=val2.split('.')}else{data___2=val2[0];temp_lst2=val2[1].split('.')}
              let last_name1=temp_lst1[temp_lst1.length-1];//最后一个变量的名字
              for (let ii=0;ii<temp_lst1.length-1;ii++){data___1=data___1[temp_lst1[ii]]}
              let last_name2=temp_lst2[temp_lst2.length-1];//最后一个变量的名字
              // console.log('data:',last_name2)
              // console.log(JSON.stringify(data___2))
              // console.log(JSON.stringify(data___2[last_name2]))
              data___1[last_name1]=data___2[last_name2];
              // console.log('data___1',data___1)
              // console.log('data___1[last_name1]',data___1[last_name1])
              // console.log('data___2',data___1)
              // console.log('data___2[last_name2]',data___2[last_name2])
              if (val2=='received_data'){data___1[last_name1]=received_data}
            }
        }
      } else {
        // 请求失败，运行回调函数
       onerror(xhr.status);
      }
    };
  
    xhr.onerror = function() {
      // 网络错误，运行回调函数
      onnetworkerror();
    };
  
    // 发送请求 
        if (method.toLowerCase()=='post' ||method.toLowerCase()=='put'  ){xhr.send(JSON.stringify(body_data));}
        else{xhr.send()}
    
  };
  }

// var func=function(data1,data2,eee,ww=5,rr=2){console.log('test_func',data1,data2,eee,ww,rr)}
// var ttteeesssttt_get=request______({method:'get',url:'/V1/color'})
// ttteeesssttt_get({
//     head_data:{"limit":[1,20]},
//     //type=func   表示运行函数 func为要运行的函数    args和kwargs为类似python的args和kwargs传参
//     //            传参的值[data1,'ddd.dd']代表 值为data1[ddd][dd] 传参的值为'count'代表 服务器传递回来的值[count]
//     //type=set_val 表示进行赋值操作 因为使用的是地址 修改后也代表原变量也被修改了
//     //            'val1':[data1,'ddd.dd'],'val2':[data2,'ddd.dd'] 表示  data1[ddd][dd]=data2[ddd][dd]
//     //            'val1':[data1,'ddd.dd'],'val2':'ddd.dd' 表示  data1[ddd][dd]=服务器传递回来的值[ddd][dd]
//     execute_lst:[
//                   {
//                     'type':'func',
//                     'func':func,
//                     'args':[[data1,'ddd.dd'],
//                     [data2,'ddd.dd'],
//                     'count',
//                     ],
//                   'kwargs':{rr:[data2,'ddd.dd']},
//                   },


//                   {'type':'set_val',
//                   'val1':"aaa",
//                   'val2':[data2,'ddd.dd']
//                   }
//     ]
// })
window.__isFull = Math.abs(window.screen.height-window.document.documentElement.clientHeight) <= 17
window.onresize = function() {
	__isFull = Math.abs(window.screen.height-window.document.documentElement.clientHeight) <= 17;
}

// 阻止F11键默认事件，用HTML5全屏API代替
window.addEventListener('keydown', function (e) {
    e = e || window.event
    if (e.keyCode===122 && !__isFull) {
        e.preventDefault()
        enterFullScreen()
    }
})

// 打开浏览器全屏模式
function enterFullScreen () {
	let el = document.documentElement
	let rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen
	if (rfs) { // typeof rfs != "undefined" && rfs
		rfs.call(el)
	}else if (typeof window.ActiveXObject !== 'undefined') {
    // for IE，这里其实就是模拟了按下键盘的F11，使浏览器全屏
		let wscript = new ActiveXObject('WScript.Shell')
		if (wscript != null) {
			wscript.SendKeys('{F11}')
		}
	}
}
 
// 退出全屏
function exitFullScreen () {
	let el = document
	let cfs = el.cancelFullScreen || el.mozCancelFullScreen || el.msExitFullscreen || el.webkitExitFullscreen || el.exitFullscreen
	if (cfs) { // typeof cfs != "undefined" && cfs
		cfs.call(el)
	} else if (typeof window.ActiveXObject !== 'undefined') {
		// for IE，这里和fullScreen相同，模拟按下F11键退出全屏
		let wscript = new ActiveXObject('WScript.Shell')
		if (wscript != null) {
			wscript.SendKeys('{F11}')
		}
	}
}

//以下调用代码根据情况自己改写
  window.set_screen=function() {
	if (__isFull) {
		exitFullScreen();
	} else {
		enterFullScreen();
	}
}

//获取 [config] 所有内容 
// window.config_now={}
// window.get_config_data=request______({method:'get',url:'get_config_data'});
// //获取配置所有内容后 需要同步更新数据的 函数 （获取最新配置后 组件需要根据最新配置来更新 组件内的数据）
// window.get_config_data_updata_funcs=[]
// window.get_config_data_updata_func=function(){console.log('config_now',config_now);for(let i=0;i<get_config_data_updata_funcs.length;i++){get_config_data_updata_funcs[i](config_now)}}
// //获取配置所有内容的触发函数
// window.get_config_data_updata=function(){get_config_data({execute_lst:[{'type':'set_val',val1:[{'val':window},'val.config_now'],val2:'received_data'},{'type':'func',func:get_config_data_updata_func}]})}


function to_time(timestamp) {  

    if (typeof timestamp === 'string'){timestamp=int(timestamp)}
    if(timestamp<9999999999){timestamp=timestamp*1000}
    // 创建一个Date对象，这个对象会自动将时间戳解析为UTC时间  
    var date = new Date(timestamp);  
      
    // 获取年、月、日、时、分、秒  
    var year = date.getUTCFullYear();  
    var month = String(date.getUTCMonth() + 1).padStart(2, '0'); // 月份是从0开始的，所以要+1  
    var day = String(date.getUTCDate()).padStart(2, '0');  
    var hours = String(date.getUTCHours() + 8).padStart(2, '0'); // 北京时间比UTC时间快8小时  
    // 注意：如果加了8小时之后超过23点，需要进位处理（这里简化处理，只考虑当天的情况）  
    if (hours >= 24) {  
        hours = hours - 24;  
        day = String(parseInt(day) + 1).padStart(2, '0');  
        // 如果日期进位后超过当月最大天数，需要处理月份和年份的进位（这里省略）  
    }  
    var minutes = String(date.getUTCMinutes()).padStart(2, '0');  
    var seconds = String(date.getUTCSeconds()).padStart(2, '0');  
      
    // 拼接成字符串并返回  
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;  
}  
  

// 使用示例  console.log(to_time(1717762464)); // 输出当前北京时间
//根据fun1返回值来执行func2 尝试max_count次数，延时时间为time_毫秒
var ttime2=function(func1,func2,func1_lst=[],func2_lst=[],max_ccount=50,ccount=0,time_=50){

  if (ccount==0){time_=0}
  if (ccount<max_ccount){
              ccount=ccount+1;
              setTimeout(function() {
              let p = func1(...func1_lst);
              
              // console.log('((((p ttime2',p)
              if (p!=false &&p!=null){
                // console.log('((((func2_lst ttime2',func2_lst)
                func2(...func2_lst)
              }else{
                ttime2(func1,func2,func1_lst,func2_lst,max_ccount,ccount,time_)
              }
              
          }, time_);
              }}
          var ttime3_wait__=function(func,func__lst=[],time_=0){setTimeout(function() {try{func(...func__lst)}catch{}}, time_);}
          //根据fun1返回值来执行func2 尝试max_count次数，延时时间为time_毫秒
          var ttime3=function(_this,ref_name,func2,func2_lst=[],max_ccount=50,ccount=0,time_=50,console_flag=false,time_wait=0){

            if (ccount==0){time_=0}
            if (ccount<max_ccount){
                        ccount=ccount+1;
                        setTimeout(function() {
                          if(console_flag){console.log('_this.$refs',_this.$refs,_this.$refs[ref_name]);
}
                        // console.log('((((p ttime2',p)
                        try{
                            if (_this.$refs[ref_name]){
                              if(console_flag){window.test_ttime3func=func2;console.log('func2:',func2);
}
                              if(time_wait!=0){ttime3_wait__(func2,func2_lst,time_wait)}
                              else{func2(...func2_lst)}
                            }else{
                              ttime3(_this,ref_name,func2,func2_lst,max_ccount,ccount,time_)
                            }}
                        catch{
                            ttime3(_this,ref_name,func2,func2_lst,max_ccount,ccount,time_)
                        }
                    }, time_);
                        }}
var ttime=function(ccount,idx,innerhtml,max_ccount,js_val=0){
                
    let time_=50;
    if (ccount==0){time_=0}
    
    if (ccount<max_ccount){
                ccount=ccount+1;
                setTimeout(function() {
                let p = document.getElementById(idx);
                if (p==null){ttime(ccount,idx,innerhtml,max_ccount)
                }else{
                    p.innerHTML = innerhtml; 
                    // console.log('js_val')
                    // console.log(js_val)
                    if (js_val){eval(js_val)}
                }
                
            }, time_);
                }}
// ttime__x
// 延时搜索id为idx的节点(没有搜索到会延时继续搜索，延时时间为0，50，50，50 总共尝试max_ccount)，
// 搜索到后然后修改这个节点内容为innerhtml
// 

// window.vuetify = new Vuetify();

function wait_run_func_class(){
    let _this=this;
    //计时器
    _this.timer=null;
    //待处理数据列表
    _this.timer_lst=[];
    //计时器运行函数
    _this.timer_func= async function(){
        while(_this.timer_lst.length){
            let new_obj=_this.timer_lst.shift();
            let func=new_obj.func;
            try{
                if(func.constructor.name === 'AsyncFunction'){
                    await func(new_obj.params);
                } else{
                    func(new_obj.params);
                }
            }catch{
                console.log("############eerrror",new_obj)
            }
            
        }
        _this.timer=null;
    };
    //给计数器运行的函数添加待处理数据  如果计时器没有开启则开启计时器
    _this.timer_start=function(obj) {  
        _this.timer_lst.push(obj);
        if(_this.timer==null){
            _this.timer = setTimeout( _this.timer_func, 0);    // 设置计时器为开启状态  
        }
    };
}

// //需要js-md5的支持 用来判断子数据是否更新
// //需要自己封装的request______
// class websocket_data_update {  
//     constructor(obj) {  
//     let _this=this;
//     //待更新的列表
//     _this.objs=[];
//     //数据
//     _this.data={};
//     //匹配路径
//     _this.check_path=function(path1,path2) {  
//         try{ 
//             let path1_lst=[],path2_lst=[];
//             if(path1!=""){path1_lst=path1.split(".");}
//             if(path2!=""){path2_lst=path2.split(".");}
//             if (path1_lst.length>path2_lst.length){
//                 for (let i=0;i<path2_lst.length;i++){
//                     if (path2_lst[i]!=path1_lst[i]){return false}
//                 }
//             }else{
//                 for (let i=0;i<path1_lst.length;i++){
//                     if (path2_lst[i]!=path1_lst[i]){return false}
//                 }

//             }
//             return true
//         }
//         catch{return false}
//         } 
//     //更新数据
//     _this.update_val=function(obj){
//         //获取要更新的数据的路径
//         let path=obj.path;
//         //获取要更新的数据
//         let update_valx=_this.data;
//         let path_lst=[]
//         if(path!=""){path_lst=path.split(".");}
//         let idx=path_lst.length-1;
//         for(let i=0;i<idx;i++){update_valx=update_valx[path_lst[i]];}
//         //更新数据
//         if (path_lst.length>0){update_valx[path_lst[path_lst.length-1]]=JSON.stringify(JSON.parse(obj.data));}
//         else{_this.data=JSON.stringify(JSON.parse(obj.data));}
//     }
//     //连接服务器的websocket
//     _this.connect_socket=function(){
//     _this.ws = new WebSocket("ws://" + window.location.host + "/websocket");
//     // WebSocket连接成功后的回调
//     _this.ws.onopen = function(event) {
//         //params 附带参数 如账号信息
//         _this.ws.send(JSON.stringify({params:_this.return_params(),"type":"get_all"}));
//     };
//     // 接收服务器消息的回调
//     _this.ws.onmessage = function(event) {
//         try{
//             //将服务器下发的数据转为json格式 {path:"更新数据的路径 为空代表所有数据","data":data}
//             let recv_data=JSON.parse(event.data);
//             if (recv_data.type=="error"){
//                 Vue.prototype.$notify({type: 'error',message: recv_data.message||'错误'});console.log("数据更新失败:",recv_data.message,recv_data);return null;}
//             //更新数据
//             _this.update_val(recv_data);
//             //更新绑定 的数据
//             let temp_val={};//{path:{"md5":xxx,"data":xxx}}
//             //更新数据的路径
//             let path1=recv_data.path;//已经更新的路径
//             let path2=null;//待匹配的路径
//             let obj=null;//待处理的对象
//             let temp_val1=null,temp_val2=null;//待匹配的路径的数据对象 和待匹配的路径的路径数组
//             let new_md5=null;//待匹配的路径的md5值
//             //运行前置函数 
//             for(let i=0;i<_this.before_objs.length;i++){
//                 obj=_this.before_objs[i];
//                 path2=obj.path;
//                 if (_this.check_path(path1,path2)){
//                     //未有相同路径 生成相关数据
//                     if (temp_val[path2]===undefined){
//                         temp_val1=_this.data;
//                         if(temp_val2!=''){temp_val2=path2.split(".");}else{temp_val2=[];}
//                         for(let j=0;j<temp_val2.length;j++){temp_val1=temp_val1[temp_val2[j]]}
//                         new_md5=md5(JSON.stringify(temp_val1));//获取最新的md5
//                         temp_val[path2]={md5:new_md5,data:temp_val1};
//                     }
//                     //md5不同 则直接更新数据
//                     if (!(obj.md5===temp_val.md5)){
//                         obj.func({path:path1,data:temp_val[path2]})
//                     }
//                 }
//             }
//             //匹配路径 然后运行函数
//             for(let i=0;i<_this.objs.length;i++){
//                 obj=_this.objs[i];
//                 path2=obj.path;
//                 if (_this.check_path(path1,path2)){
//                     //未有相同路径 生成相关数据
//                     if (temp_val[path2]===undefined){
//                         temp_val1=_this.data;
//                         if(temp_val2!=''){temp_val2=path2.split(".");}else{temp_val2=[];}
//                         for(let j=0;j<temp_val2.length;j++){temp_val1=temp_val1[temp_val2[j]]}
//                         new_md5=md5(JSON.stringify(temp_val1));//获取最新的md5
//                         temp_val[path2]={md5:new_md5,data:temp_val1};
//                     }
//                     //md5不同 则直接更新数据
//                     if (!(obj.md5===temp_val.md5)){
//                         try{obj.func({path:path1,data:temp_val[path2]})}
//                         catch{
//                             if(obj[error_count]===undefined){obj[error_count]=1;}
//                             else{obj[error_count]++;}
//                             if (obj.type=='try1'&&obj[error_count]>1){_this.objs.slice(i,1);i--;}
//                             else if (obj.type=='try2'){_this.objs.slice(i,1);i--;}
//                         }
                        
//                     }
//                 }
//             }
//         }
//         catch{Vue.prototype.$notify({type: 'error',message: 'event.data错误'});console.log("event.data:",event.data)}
//     };

//     // WebSocket关闭时的回调
//     _this.ws.onclose = function(event) {
//         console.log("websocket已经关闭.");
//         _this.connect_socket();
//     };
//     // 错误处理
//     _this.ws.onerror = function(error) {
//         console.error("WebSocket错误:", error);
//     };
//     }
    
//     // 添加前置执行函数 func({"func":func,"path":path})
//     // path为要监听的路径 通过判断path路径的md5值是否一致来更新 如果path路径不存在 则不执行
//     _this.before_objs=[];
//     _this.add_before_func=function(obj){
//         _this.before_objs.push(obj);
//     }
//     //注册全局配置对象   register({"type":"try1","func":"要运行","param_path":xx.xx.xx,"recv_func":func})
//     //     type:'try1',//首次执行报错跳过，后续再执行如果报错就删除当前对象
//     //     type:'try2',//执行后如果报错就删除对象
//     //     type:'try3',//报错不删除对象
//     //     func:'',//要运行的函数名称
//     //     check_param_path:'',//要检查的数据有变动的索引  如{a:{b:1}}变为{a:{b:2}} 这里值就为a.b
//     //     recv_func:'' //向服务器更新数据的请求回调函数
//     // 注册后 获得主动获取数据的函数
//     // get_data(now_data) 主动获取注册路径的数据 now_data为当前数据
//     _this.register=null
//     // 注册更新
//     // 当数据更新、初始化时 会判断目标路径的值的md5是否产生变化 产生变化则 将变化后的数据传入回调函数中
//     _this.match_obj=function(obj){
//         for(let i=0;i<_this.objs.length;i++){
//             if(_this.objs[i]==obj){return i}
//         }
//     }
//     _this.register=function(obj_data){
//         _this.objs.push(obj_data);
//         let obj=obj_data;
//         //主动获取注册路径的数据
//         let get_data=function(now_data){
//             let now_md5=md5(JSON.stringify(now_data));//获取当前的md5
//             let path=obj.path;
            
//             let temp_val1=_this.data,temp_val2=[];
//             if(temp_val2!=''){temp_val2=path2.split(".");}
//             for(let j=0;j<temp_val2.length;j++){temp_val1=temp_val1[temp_val2[j]]}
//             let new_md5=md5(JSON.stringify(temp_val1));//获取最新的md5
//             //md5不同 则直接更新数据
//             if (!(new_md5===now_md5)){
//                 try{obj.func({path:path,data:temp_val1})}
//                 catch{
//                     let del_idx=null;
//                     if (obj.type=="try1" || obj.type=="try2"){del_idx=_this.match_obj(obj);}
//                     if(obj[error_count]===undefined){obj[error_count]=1;}
//                     else{obj[error_count]++;}
//                     if (obj.type=='try1'&&obj[error_count]>1){
//                         _this.objs.slice(del_idx,1);}
//                     else if (obj.type=='try2'){_this.objs.slice(del_idx,1);}
//                 }
//             }
//         }
//         return get_data
//     }  
// //向服务器更新数据 obj={"path:"xx.xx.xx","data":"data"} path为要更新的完整路径
//     _this.update=function(update_obj){
//         update_obj.params=_this.return_params();//添加附带参数如账号信息
//         update_obj.type="update";//表示更新数据
//         _this.ws.send(JSON.stringify(update_obj));//向服务器发送数据
//     }
//     }
    
//   }  
    
// //   // 创建对象  
// //   let test = new data_update({"data":{'a':{"b":1}}});  
// //    obj={
// //             type:'try1',//首次执行报错跳过，后续再执行如果报错就删除当前对象
// //             func:function(data){console.log('更新:',data)},//要运行的函数名称
// //             check_param_path:'a.b',//要检查的数据有变动的索引  如{a:{b:1}}变为{a:{b:2}} 这里值就为a.b
// //         }
// //   test.add(obj)
// //   test.update();
// //   test.data.a.b=3;
// //   test.update();
// //   test.update();
// //   //通过请求获取数据
  
// //   obj2={
// //     type:"request",//通过请求获取数据
// //     method:"get",//请求类型
// //     url:'请求url',//
// //     data:'初始数据',
// //     }
// //   window.config_now = new data_update(obj2);  

function main_color() {
    let _this=this;
    _this.base_color=["rgba(0,0,0,0)","#000000","#8e8e8e","#ffffff"];
    _this.dom=null;
    _this.now_select="";
    _this.color_dct={
        "明亮": ["#4992ff","#7cffb2","#fdd360","#ff6e76","#58d9f9","#05c091"],
        "暗淡": ["#5470c6","#91cc75","#fac858","#ee6666","#73c0de","#3ba272"],
        "马卡龙": ["#2ec7c9","#b6a2de","#5aa1ef","#ffb980","#d87a80","#8d98b3"],
        "蓝绿": ["#3fb1e3","#6beec1","#626c91","#a0a7e6","#c4ebad","#96dee8"],
        "深紫": ["#9b8bba","#e098c7","#8fd3e8","#71669e","#cc70af","#7cb4cc"],
        "复古": ["#d87c7c","#919e8b","#d7ab82","#6e7074","#61a0a8","#efa18d"],
        "粉青": ["#fc97af","#87f7cf","#f7f494","#72ccff","#f7c5a0","#d4a4eb"],
        "灰粉": ["#516b91","#59c4e6","#edafb2","#93b7e3","#a5e7f0","#cbb0e3"],
        "青草": ["#4ea397","#22c3aa","#7bd9a5","#d0648a","#f58db2","#f2b3c9"],
        "橘红": ["#893448","#d95850","#eb8146","#ffb248","#f2d643","#ebdba4"],
        "深色": ["#c12e34","#e6b600","#0098d9","#2b821d","#005ea6","#339ca8"],
        "罗马红": ["#e01f54","#5e4ea5","#f5e8c8","#b8d2c7","#c6b38e","#a4d8c2"]
    };
    _this.now_name=0;
    _this.reset=function(){
        _this.names=Object.keys(_this.color_dct);
    }
    _this.reset();
    _this.add_color=function(obj){
        for(let k in obj){
            _this.color_dct[k]=obj[k];
        }
        _this.reset();
    };
    _this.change_color=function(name){
        _this.now_name=_this.names.indexOf(name);
        let i=0;
        let styles="";
        for (let j=0;j<_this.base_color.length;j++,i++){
            styles=styles+`--color${i}-main_color:${_this.base_color[j]};`
        }
        for (let j=0;j<_this.color_dct[name].length;j++,i++){
            styles=styles+`--color${i}-main_color:${_this.color_dct[name][j]};`
        }
        styles=":root{"+styles+"}";
        _this.dom.textContent = styles;
    };
    _this.change_next=function(){
        _this.now_name++;
        if(_this.now_name>(_this.names.length-1)){_this.now_name=0}
        _this.change_color(_this.names[_this.now_name]);
    }
    // 检查是否已经存在ID为main_color的<style>标签
    let dom = document.getElementById('__ea__base_color_id');
    
    if (!dom) {
        // 如果不存在，则创建一个新的<style>标签并添加到<head>中
        _this.dom = document.createElement('style');
        _this.dom.id = 'main_color';
        _this.dom.type = 'text/css';
        document.head.appendChild(_this.dom);
        _this.change_color(_this.names[_this.now_name]);
    }
    
    // 可以在这里添加其他实例方法或属性
}
window.main_color_obj=new main_color();
// window.main_color_obj.change_color("罗马红");
// window.main_color_obj.change_next();
function __ea__base_css(){
    let _this=this;
    _this.num=6;//css权重
    /*创建css基础样式 -border*/
    _this.create_base_border=function(v=24){
        let style_val="";
        let a=["s","o","a","d"],b=["","-r","-l","-t","-b","-x","-y"];
        let h=["solid","dotted","dashed","double"];
        let c=[".ea_b#x#x","{#x}","border#x-style:#x;border#x-width:#xpx;"];
        let d={"-r":["-right"],"-l":["-left"],"-t":["-top"],"-b":["-bottom"],"-x":["-right","-left"],"-y":["-top","-bottom"],"":[""]};
        for (let x=0;x<=v;x++){
            for (let i=0;i<a.length;i++){
                for(let j=0;j<b.length;j++){
                        let e=c[0],f=d[b[j]],g="";
                        e = e.replace(/#x/,a[i]+b[j]).replace(/#x/,"-"+x);
                        let u=e;
                        for(let i=0;i<_this.num;i++){
                            e=e+u;
                        }
                        for (let m=0;m<f.length;m++){
                            g=g+c[2].replace(/#x/,f[m]).replace(/#x/,h[i]).replace(/#x/,f[m]).replace(/#x/,x);
                        }
                        let y=c[1];
                        e = e+y.replace(/#x/,g);
                        style_val=style_val+e;
                }
            }
        }
        return style_val

    };
    /*创建css基础样式 -margin*/
    _this.create_base_margin=function(v=[-24,24]){
        let style_val="";
        let b=["","r","l","t","b","x","y"];
        let c=[".ea_m#x#x","{#x}","margin#x:#xpx;"];
        let d={"r":["-right"],"l":["-left"],"t":["-top"],"b":["-bottom"],"x":["-right","-left"],"y":["-top","-bottom"],"":[""]};
        for (let x=v[0];x<=v[1];x++){
                for(let j=0;j<b.length;j++){
                        let e=c[0],f=d[b[j]],g="";
                        e = e.replace(/#x/,b[j]).replace(/#x/,"-"+x);
                        let u=e;
                        for(let i=0;i<_this.num;i++){
                            e=e+u;
                        }
                        for (let m=0;m<f.length;m++){
                            g=g+c[2].replace(/#x/,f[m]).replace(/#x/,x*4);
                        }
                        let y=c[1];
                        e = e+y.replace(/#x/,g);
                        style_val=style_val+e;
                }
        }
        return style_val

    };
    /*创建css基础样式 -padding*/
    _this.create_base_padding=function(v=[0,24]){
        let style_val="";
        let b=["","r","l","t","b","x","y"];
        let c=[".ea_p#x#x","{#x}","padding#x:#xpx;"];
        let d={"r":["-right"],"l":["-left"],"t":["-top"],"b":["-bottom"],"x":["-right","-left"],"y":["-top","-bottom"],"":[""]};
        for (let x=v[0];x<=v[1];x++){
                for(let j=0;j<b.length;j++){
                        let e=c[0],f=d[b[j]],g="";
                        e = e.replace(/#x/,b[j]).replace(/#x/,"-"+x);
                        let u=e;
                        for(let i=0;i<_this.num;i++){
                            e=e+u;
                        }
                        for (let m=0;m<f.length;m++){
                            g=g+c[2].replace(/#x/,f[m]).replace(/#x/,x*4);
                        }
                        let y=c[1];
                        e = e+y.replace(/#x/,g);
                        style_val=style_val+e;
                }
        }
        return style_val

    };
    /*创建css基础样式 -font*/
    _this.create_base_font1=function(v=[0,24]){
        let style_val="";
        let a=0.5,b=".ea_f-#x",y="{font-size:#xrem}";
        for (let x=v[0];x<=v[1];x++){
            let e=b.replace(/#x/,x);
            let u=e;
            for(let i=0;i<_this.num;i++){
                e=e+u;
            }
            c=e+y.replace(/#x/,a+x*0.25);
            style_val=style_val+c;
        }
        return style_val

    };
    _this.create_base_font2=function(v=[1,9]){
        let style_val="";
        let a=100,b=".ea_fw-#x",y="{font-weight:#x}";
        for (let x=v[0];x<=v[1];x++){
            let e=b.replace(/#x/,x);
            let u=e;
            for(let i=0;i<_this.num;i++){
                e=e+u;
            }
            c=e+y.replace(/#x/,a*x);
            style_val=style_val+c;
        }
        return style_val
    };

    /*创建css基础样式 -height*/
    _this.create_base_height=function(v=[0,24]){
        let style_val="";
        let a=0.75,b=".ea_h-#x",y="{height:#xrem}";
        for (let x=v[0];x<=v[1];x++){
            let e=b.replace(/#x/,x);
            let u=e;
            for(let i=0;i<_this.num;i++){
                e=e+u;
            }
            c=e+y.replace(/#x/,a+x*0.5);
            style_val=style_val+c;
        }
        return style_val

    };
    /*创建css基础样式 -scale*/
    _this.create_base_scale=function(v=[0,30]){
        let style_val="";
        let a=0.1,b=".ea_scale-#x",y="{scale:#x}";
        for (let x=v[0];x<=v[1];x++){
            let e=b.replace(/#x/,x);
            let u=e;
            for(let i=0;i<_this.num;i++){
                e=e+u;
            }
            c=e+y.replace(/#x/,a+x*0.1);
            style_val=style_val+c;
        }
        return style_val

    };
    /*创建css基础样式 -shadow*/

    /*创建*/
    _this.create_css=function(){
    let id_="__ea__base_css_id";
    var element = document.getElementById(id_);
    if (!element) {
        let styleElement = document.createElement('style');
        styleElement.id = id_;
        let head = document.head || document.getElementsByTagName('head')[0];
        let set_style="@media(min-width: 0px){html{overflow-y:auto!important}}";
        set_style=set_style+_this.create_base_border();
        set_style=set_style+_this.create_base_margin();
        set_style=set_style+_this.create_base_padding();
        set_style=set_style+_this.create_base_font1();
        set_style=set_style+_this.create_base_font2();
        set_style=set_style+_this.create_base_height();
        set_style=set_style+_this.create_base_scale();
        styleElement.innerHTML=set_style;
        head.appendChild(styleElement);
    }
    };
}
window.__ea__base_css_obj=new __ea__base_css();
t=__ea__base_css_obj.create_css();

// console.log(__ea__base_css_obj.create_base_font1())

//n表示保留几位小数
function keepTwoDecimalFull(num,n=1) {  
    if (typeof n === 'string')n=parseInt(n, 10);  
    var result = parseFloat(num);  
    if (isNaN(result)) {  
        alert('传递参数错误，请检查！');  
        return false;  
    }  
    tev=Math.pow(10, n)
    result = Math.round(num * tev) / tev;  
    var s_x = result.toString(); //将数字转换为字符串
    
    var pos_decimal = s_x.indexOf('.'); //小数点的索引值
    
  
    // 当整数时，pos_decimal=-1 自动补0  
    if (pos_decimal < 0) {  
        pos_decimal = s_x.length;  
        s_x += '.';  
    }
  
    // 当数字的长度< 小数点索引+2时，补0  
    while (s_x.length <= pos_decimal + n) {  
        s_x += '0';  
    }  
    return s_x;  
  } 
function vue_temp_change_name(str) {  
    let res= str.replace(/_([a-z])/g, (match, letter) => letter.toUpperCase()); 
    return res.replace(/_/g,'') 
   }  

//需要js-md5的支持 用来判断子数据是否更新
//需要自己封装的request______
class data_update {  
    constructor(obj) {  
        // obj={
        //     type:"request",//通过请求获取数据
        //     method:"get",//请求类型
        //     url:'请求url',//
        //     data:'初始数据',
        // }
      
      let _this=this;
      _this.init_flag=false;//是否完成第一次获取配置
      _this.init_func_lst=[];//在获取第一次数据前 要运行的配置函数
      _this.set_init_flag_ok=function(){
        _this.init_flag=true//完成第一次获取配置
        console.log("运行待处理函数",_this.init_func_lst.length);
        for (let i=0;i<_this.init_func_lst.length;i++){_this.init_func_lst[i]();}//开始分配配置数据
    }
      //数据
      _this.data={};
      if (obj.data){_this.data=JSON.parse(JSON.stringify(obj.data));}
      //前置执行的函数
      _this.before_funcs=[];
      //待更新的列表
      _this.update_func_lst=[]; 
      //获取数据
      if (obj.type=='request'){
        _this.request=request______({method:obj.method,url:obj.url});
        _this.get=function(){
            _this.request({execute_lst:[
                {'type':'set_val',val1:[{'val':_this},'val.data'],val2:'received_data'},
                {'type':'func',func:_this.update},
                {"type":"func",func:_this.set_init_flag_ok}
            ]})
                

        };
      }

    // 添加前置执行函数
    _this.add_before_func=function(func){
        _this.before_funcs.push(func);
    }
    // 增加待更新函数
    _this.add=function(obj){
        // obj={
        //     type:'try1',//首次执行报错跳过，后续再执行如果报错就删除当前对象
        //     type:'try2',//执行后如果报错就删除对象
        //     type:'try3',//报错不删除对象
        //     func:'',//要运行的函数名称
        //     check_param_path:'',//要检查的数据有变动的索引  如{a:{b:1}}变为{a:{b:2}} 这里值就为a.b
        // }
        obj.old_md5_val='';//最新数据与此md5比对 相同则不更新
        obj.try1_flag=0;//try1的参数 0表示没有运行过 1表示运行过一次
        _this.update_func_lst.push(obj);
        //主动获取数据的函数函数
        let res_func=function(){
            if (_this.init_flag==false){
                console.log("将当前函数存入待处理");
                wait_res_func();//将当前函数存入待处理
                return null;
            }
            let temp=_this.data;
            let temp2 = obj.check_param_path.split(".");  
            for(let j=0;j<temp2.length;j++){temp=temp[temp2[j]]}
            try{obj.func(temp);}catch{}
        }
        let wait_res_func=function(){_this.init_func_lst.push(res_func);}
        return res_func
    }
      _this.update=function(){
        //先执行 _this.before_funcs
        for(let i=0;i<_this.before_funcs.length;i++){
            try{_this.before_funcs[i](_this.data);}catch{}
        }
        let temp={};//要更新的数据
        let temp2=[];//拆分的字符串
        let new_md5_val='';
        for (let i=_this.update_func_lst.length-1;i>=0;i--){
            obj=_this.update_func_lst[i];
            console.log("start try")
            try{
                temp=_this.data;
                temp2 = obj.check_param_path.split(".");  
                for(let j=0;j<temp2.length;j++){temp=temp[temp2[j]]}
                new_md5_val=md5(JSON.stringify(temp));//获取最新的md5
                if (new_md5_val!=obj.old_md5_val){
                    obj.func(temp);//运行函数 更新数据
                    obj.old_md5_val=new_md5_val;//更新md5
                    if (obj.try1_flag==0){obj.try1_flag=1;}//更新try1标志
                }
            }catch{
                if((obj.type=='try1'&&obj.try1_flag==1) || (obj.type=='try2')){
                    _this.update_func_lst.slice(i,1);//删除
                }
            }
        }
    };
    _this.get_data=function(){
        return _this.data
    }  
    }
    
  }  
    
//   // 创建对象  
//   let test = new data_update({"data":{'a':{"b":1}}});  
//    obj={
//             type:'try1',//首次执行报错跳过，后续再执行如果报错就删除当前对象
//             func:function(data){console.log('更新:',data)},//要运行的函数名称
//             check_param_path:'a.b',//要检查的数据有变动的索引  如{a:{b:1}}变为{a:{b:2}} 这里值就为a.b
//         }
//   test.add(obj)
//   test.update();
//   test.data.a.b=3;
//   test.update();
//   test.update();
//   //通过请求获取数据
  
//   obj2={
//     type:"request",//通过请求获取数据
//     method:"get",//请求类型
//     url:'请求url',//
//     data:'初始数据',
//     }
//   window.config_now = new data_update(obj2);  
window.___lhp_run_func_lhp_loop_time_func=function(str_,obj=null){
  try{
    console.log("str_:",str_)
      if (str_==''){return null;}
      else if (str_.includes('.')){
          let arr = str_.split('.');  
          let run_func=window
          for (let i=0;i<arr.length-1;i++){ run_func=run_func[arr[i]]}
          if (obj!=null){
              let res=run_func[arr[arr.length-1]](obj)
              console.log("run_func",run_func)
              console.log("arr.length-1",arr.length-1)
              console.log("arr",arr)
              console.log("obj",obj)
              console.log(str_,"得到返回值1:",res)
              return res
          }else{
            let res=run_func[arr[arr.length-1]]()
            console.log(str_,"得到返回值2:",res)
            return res
          }
      }else{
          if (obj!=null){
            let res=window[str_](obj)
            console.log(str_,"得到返回值3:",res)
            return res
          }else{
            let res=window[str_]()
            console.log(str_,"得到返回值4:",res)
            return res
          }
      }
      
}catch{}
}
window.___lhp_run_func_lhp_loop_time_func_check=function(str_){
  // console.log("检查函数"+str_+"是否存在:",str_)
  if (str_==''){return true;}
  else if (str_.includes('.')){
      let arr = str_.split('.');  
      let run_func=window
      try{for (let i=0;i<arr.length;i++){ run_func=run_func[arr[i]]}}
      catch{
        // console.log("不存在")
        return false
      }


      if (run_func!=undefined && run_func!=null){
        console.log("存在")
          return true
      }else{
        // console.log("不存在")
          return false
      }
}
}



window.lhp_loop_time=1000;
window.lhp_loop_time_funcs=[];
window.lhp_loop_time_obj=null;
window.lhp_loop_time_func=function(){
  clearTimeout(lhp_loop_time_obj);//清除定时器
  for (let i=0;i<lhp_loop_time_funcs.length;i++){
    let item=lhp_loop_time_funcs[i];
    //匹配循环的时间:
    if (item.now_time==null || item.now_time==undefined){item.now_time=1;}else{item.now_time++;}
    if (item.now_time>=item.time){
      item.now_time=0;
      let res=null;
      if (typeof item.func === 'string') {  
      //调用字符串函数
      console.log("___lhp_run_func_lhp_loop_time_func_check(item.func)",item,___lhp_run_func_lhp_loop_time_func_check(item.func))
      if(___lhp_run_func_lhp_loop_time_func_check(item.func)){
        if (item.params!=undefined){try{res=___lhp_run_func_lhp_loop_time_func(item.func,item.params)}catch{}
        }else{try{res=___lhp_run_func_lhp_loop_time_func(item.func)}catch{}}
      }else{continue}
        
      }else{
        //调用普通函数
        if (item.params!=undefined){try{res=item.func(item.params)}catch{}
        }else{try{res=item.func()}catch{}}
      }
      


      if (item.callback!=undefined){if(res!=undefined){try{item.callback(res)}catch{}}else{try{item.callback()}catch{}}}
      if (item.once==true){console.log("删除！",item);
window.lhp_loop_time_funcs.splice(i,1);i--;}
    }
  //如果有最大计数值 则删除
  if(item.count===undefined){item.count=0}else{item.count++;}
  if((!(item.count_max===undefined))&&(item.count>item.count_max)){window.lhp_loop_time_funcs.splice(i,1);i--;}
  }
  lhp_loop_time_obj = setTimeout(lhp_loop_time_func, lhp_loop_time); //设定定时器，循环运行
}
lhp_loop_time_obj = setTimeout(lhp_loop_time_func, 100); //开始运行
//只运行一次
//obj:{
//"info":"基本信息",
//"func":要运行的函数, //如果为字符串 则会判断是否存在 如果存在此函数 才会运行 如果超过20秒 此函数依旧不存在会打印信息到终端
//
//"params":"传参","time":1[代表100毫秒运行一次],"once":true[代表运行一次就删除无论是否报错]
//      "callback":回调函数【如果运行func后返回值不为undefined会传入func的返回值作为回调函数的参数】
//}
window.lhp_start_loop_once=function(obj){
  obj.once=true;
  if(obj.time==undefined || obj.time==null){obj.time=1;}
  window.lhp_loop_time_funcs.push(obj)
}
window.lhp_start_loop=function(obj){if(obj.time==undefined || obj.time==null){obj.time=1;}
window.lhp_loop_time_funcs.push(obj);}





// let test_obj={
// func:'测试.打印222',
// "params":{"参数":"打印222回调完成"},
// callback:function(params){console.log("回调参数:",params)}}
// lhp_start_loop_once(test_obj);

// let test_obj2={
//   time:10,//1秒后运行
//   func:function(){console.log("设置测试.打印222函数完成");lhp_deepcopy1(window,{"测试":{"打印222":function(params){console.log("测试打印:222");return params}}})},}
// lhp_start_loop(test_obj2);

class lhp_set_config_websocket_set_data{
    static lhp_deepcopy2(a,path,__b){
        if (typeof __b !== 'object' || __b === null ||path=='') {  
          //   console.log("???")
            return ;  
        }  
        __b=JSON.parse(JSON.stringify(__b));
        let path_lst=path.split(".");
        for(let i=0;i<path_lst.length-1;i++){a=a[path_lst[i]]}
        let stack=[]
        stack.push([[],__b])
       //  console.log("stack:",stack)
        while( stack.length){
            let new_stack=[]
            for (let i =0;i<stack.length;i++){
                let item=stack[i]
                let key=item[0],value=item[1]
                let temp_val=a
                let temp_b=__b
                if (key.length==0){
                    let kkpath=path_lst[path_lst.length-1];
                    if (kkpath in temp_val){
                        //为对象 则加入深度遍历队列 等待下一轮遍历
                        if(typeof temp_b === 'object'&&temp_b!=null&& temp_val[kkpath]!=null){for (
                         let k in temp_b){new_stack.push([ [...key, k],temp_b[k]])}}
                        //不为对象  则直接覆盖
                        else{
                      //   console.log('不拥有直接覆盖1',key,temp_b)
                            temp_val[kkpath]=temp_b}
                    }
                    //不拥有 则直接覆盖
                    else{
                      //   console.log('不拥有直接覆盖2',key,temp_b)
                        //如果是数组 则直接插入
                        if (Array.isArray(temp_val)){
                            temp_val.push(temp_b)
                        }else{
                        //不是数组 就按照对象设置属性
                            temp_val[kkpath]=temp_b
                        }
                        
                    }
                break}
                temp_val=temp_val[path_lst[path_lst.length-1]]
                for(let j =0;j<key.length;j++){temp_b=temp_b[key[j]]}
                for(let j =0;j<key.length-1;j++){temp_val=temp_val[key[j]]}
                
                //如果a 拥有b这个属性 判断是否为对象，从而进行深度遍历
                if (key[key.length-1] in temp_val){
                   //  console.log("如果a拥有b这个属性",key[key.length-1])
                    //为对象 则加入深度遍历队列 等待下一轮遍历
                    if(typeof temp_b === 'object' &&temp_b !=null && temp_val[key[key.length-1]]!=null){
                      
                      // console.log("????")
                      for (let k in temp_b){
                        new_stack.push([ [...key, k],temp_b[k]])}}
                    //不为对象  则直接覆盖
                    else{
                   //  console.log('不拥有直接覆盖3',key,temp_b)
                        temp_val[key[key.length-1]]=temp_b}
                }
                //不拥有 则直接覆盖
                else{
                   //  console.log('不拥有直接覆盖4',key,temp_b)
                    //如果是数组 则直接插入
                    if (Array.isArray(temp_val)){
                        temp_val.push(temp_b)
                    }else{
                    //不是数组 就按照对象设置属性
                        temp_val[key[key.length-1]]=temp_b
                    }
                    
                }
                
            }
            stack=new_stack
        }
    
    }
    static postput(obj={}){
        // console.log('数据对象更新:',obj)
        try{
  
            this.lhp_deepcopy2(obj.data,obj.path,obj.copy_data);
            return {"type":'ok'}
        }
        catch(err){
            return {"type":'error',"message":"lhp_set_config_websocket_set_data postput异常"+err}
        }
    }
    static delete(obj={}){
        try{
            let change_obj=obj.data;
            if (obj.path.indexOf(".") !== -1){
                let path_lst=obj.path.split(".");
                if (path_lst.length<=1){return {"type":'error',"message":"delete异常 数量小于等于1"}}
                for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
                if(typeof change_obj =="object") {  
                    if (Array.isArray(change_obj)){
                        change_obj.splice(path_lst[path_lst.length-1],1);
  
                    }else{
                        delete change_obj[path_lst[path_lst.length-1]]
                    }
            }}else{return {"type":'error',"message":"delete异常 数量小于2"}}
            return {"type":'ok'}
  
        }catch(err){return {"type":'error',"message":"lhp_set_config_websocket_set_data delete异常"+err}}
    }
    static clear(obj={}){
        try{
            let md5_val=null;
            let res={"type":'ok'}
            let change_obj=obj.data;
            let last_key=null;
            if (obj.path.indexOf(".") !== -1){
                let path_lst=obj.path.split(".");
                for (let i=0;i<path_lst.length-1;i++){change_obj=change_obj[path_lst[i]]}
                last_key=path_lst[path_lst.length-1];
            }else{
                last_key=obj.path;
            
            }
            let temp_val=change_obj[last_key]
            if (typeof temp_val=='object') {  
                // 注意：这里会匹配到null，因为null也是object类型  
                // 需要额外检查是否为null  
                if (temp_val === null) {  
                    change_obj[last_key] = null; // 或者你可以将null也设置为{}  
                } else if (Array.isArray(temp_val)) {  
                    change_obj[last_key] = [];  
                    md5_val=[];
                } else {  
                    change_obj[last_key] = {};  
                    md5_val={};
                }  
            }else if (typeof temp_val=='string'){
            change_obj[last_key] = '';  
            md5_val='';
            }else if (typeof temp_val=='number'){
            change_obj[last_key] = 0;  
            md5_val=0;
            }else if (typeof temp_val=='boolean'){ 
            change_obj[last_key] = false;  
            md5_val=false;}
        // console.log("clear params obj",obj)
        // console.log("change_obj[last_key]",change_obj[last_key])
        // console.log("md5_val",md5_val)
        if(obj.md5_flag==true){res.md5=md5(JSON.stringify(md5_val))}
        return obj
  
        }catch(err){
            return {"type":'error',"message":"lhp_set_config_websocket_set_data clear异常"+err}
        }
    }
    
  static insert(obj={}){
    console.log("config insert1 obj",3,obj);
    try{
        // let path=obj.path;//要插入的路径
        let path_lst=obj.path.split(".");
        let before_idx=obj.before_idx;//要插入到第几个元素之前
        let change_obj=obj.data;//要插入的数据
        if (path_lst.length<=1){return {"type":'error',"message":"delete异常 数量小于等于1"}}
        for (let i=0;i<path_lst.length;i++){change_obj=change_obj[path_lst[i]]}
        if (before_idx===null || (before_idx===undefined)){
            console.log("config insert2",2,'追加数据');
            change_obj.push(obj.copy_data);
        }else{
            console.log("config insert2",2,'-1插入数据前',JSON.parse(JSON.stringify(change_obj)));
            change_obj.splice(before_idx,0,obj.copy_data); 
            console.log("config insert2",2,'-2插入数据后',JSON.parse(JSON.stringify(change_obj)));
        }
        console.log("config insert3 insert后的数据",3,JSON.parse(JSON.stringify(obj.data)));
        return {"type":'ok'}

    }catch (err){
        let error_message= {"type":'error',"message":"lhp_set_config_websocket_set_data insert异常"}
        console.log(error_message,'\n',err);
        return error_message}
  }
  static set(obj){
    //obj.base_data 是原数据
if (obj.type=="change_data"){
    if(obj.data_type=="postput"){
            let res=lhp_set_config_websocket_set_data.postput({
                data:obj.base_data,
                path:obj.path,
                copy_data:obj.data
            })
            if(res.type=="error"){
                console.log(res.message);
                return
            }
    }
    else if(obj.data_type=="delete"){
        let res=null;
        if (typeof obj.path==='string'){
            res=this.delete({
            data:obj.base_data,
            path:obj.path,
            })
            if(res.type=="error"){
                console.log(res.message);
                return
            }
        }
        else if( Array.isArray(obj.path)){
            for (let zzzz=0;zzzz<obj.path.length;zzzz++){
                res=this.delete({
                data:obj.base_data,
                path:obj.path[zzzz],
                })
                if(res.type=="error"){
                    console.log(res.message);
                    return
                }

            }
        }
    }
    else if (obj.data_type=="clear"){
    
    let res=lhp_set_config_websocket_set_data.clear({
        md5_flag:true,
        data:obj.base_data,
        path:obj.path,
    })
if(res.type=="error"){
    console.log(res.message);
    return
}
    }
    else if(obj.data_type=='set_list'){
        if(!(obj.delete===undefined)){
        for (let idx_=0;idx_<obj.delete.length;idx_++){
            if (typeof obj.delete[idx_].path==='string'){
                res=lhp_set_config_websocket_set_data.delete({
                data:obj.base_data,
                path:obj.delete[idx_].path,
                })
            }else if( Array.isArray(obj.delete[idx_].path)){
                for (let zzzz=0;zzzz<obj.delete[idx_].path.length;zzzz++){
                    res=lhp_set_config_websocket_set_data.delete({
                    data:obj.base_data,
                    path:obj.delete[idx_].path[zzzz],
                    })

                }
            }
        }
        }
        if(!(obj.clear===undefined)){
            for (let idx_=0;idx_<obj.clear.length;idx_++){
                let res=lhp_set_config_websocket_set_data.clear({
                    md5_flag:true,
                    data:obj.base_data,
                    path:obj.clear[idx_].path,
                })
            }
        }
        if(!(obj.postput===undefined)){

            for (let idx_=0;idx_<obj.postput.length;idx_++){
                let res=lhp_set_config_websocket_set_data.postput({
                    md5_flag:true,
                    data:obj.base_data,
                    path:obj.postput[idx_].path,
                    copy_data:obj.postput[idx_].data
                })
            }
        }
        if(!(obj.insert===undefined)){

            for (let idx_=0;idx_<obj.insert.length;idx_++){
                let res=lhp_set_config_websocket_set_data.insert({
                    md5_flag:true,
                    data:obj.base_data,
                    path:obj.insert[idx_].path,
                    copy_data:obj.insert[idx_].data,
                    before_idx:obj.insert[idx_].before_idx
                }) 
            }
        }
}

}
  }
}
window.component2_edit_flag=true;
component2_props_add_data={
    var_name:"",//绑定的变量名 编辑状态下可能会使用的参数
    all_set_data:null,//所有的数据
    con2_father_this: null,
    con2_idx: "",
    deepcopy_data:null,//用于传递参数
};

log_flag=false
log_print=function(...args){
        if(log_flag==true){
            console.log(...args)
        }
    }
component2_data_add_data__={
    var_name:'',//用于设置组件的全局访问对象
    __test_flag:false,//组件用到的测试参数
    body_data:[],
    // ___name:name_,//组件名称
    __father_this:null,//作为属性容器下的子组件 可以通过此直接访问属性容器的this
    __child_idx:null,//作为 
    __only_id:"test",//项目中被渲染的组件id: 项目拥有者id_项目目录id_项目id_页面id_组件id
    __style:{
        __edit_flag__:true,//如果该组件处于编辑状态 是否启用var_name
        __height:"100%",//高度
        __width:"100%",//宽度
        __margin:"null",
        __margin_x:"null",
        __margin_y:"null",
        __margin_right:"0px",//
        __margin_left:"0px",//
        __margin_top:"0px",//
        __margin_bottom:"0px",//
        __padding:"null",
        __padding_x:"null",
        __padding_y:"null",
        __padding_left:"0px",//
        __padding_right:"0px",//
        __padding_top:"0px",//
        __padding_bottom:"0px",//
    }
}
component2_data_add_data=function(name_,data,new_component2_data_add_data__){
    let res=function(){
        let val_obj=data();
        new_component2_data_add_data__.___name=name_;//组件名称
        let res_val={data:JSON.parse(JSON.stringify(new_component2_data_add_data__))};
        // console.log("new_component2_data_add_data__",JSON.parse(JSON.stringify(new_component2_data_add_data__)))
        // console.log("val_obj",JSON.parse(JSON.stringify(val_obj)))
        lhp_deepcopy1(res_val,val_obj)
        return res_val
    }
    return res
}
component2_methods_add_data={
    get_ref:function(ref_name){
        try{
            let ref_obj=this.$refs[ref_name];
            if(Array.isArray(ref_obj)){ref_obj=ref_obj[0];}
            return ref_obj
        }catch{
        throw new Error(this,this.data.var_name,'不存在这个ref名称:',ref_name); 
        }
    },
    _log:function(...lst){if(this.data.__test_flag){console.log(...lst)}},
    ___set_width:function(name,e){this.$refs[name].width=e},
    ___set_height:function(name,e){this.$refs[name].height=e},
    ___set_padding_left:function(name,e){this.$refs[name].style['paddingLeft']=e},
    ___set_padding_right:function(name,e){this.$refs[name].style['paddingRight']=e},
    ___set_padding_top:function(name,e){this.$refs[name].width.style['paddingTop']=e},
    ___set_padding_bottom:function(name,e){this.$refs[name].style['paddingBottom']=e},
    ___set_margin_left:function(name,e){this.$refs[name].style['marginLeft']=e},
    ___set_margin_right:function(name,e){this.$refs[name].style['marginRight']=e},
    ___set_margin_top:function(name,e){this.$refs[name].style['marginTop']=e},
    ___set_margin_bottom:function(name,e){this.$refs[name].style['marginBottom']=e},
    //编辑状态下禁止启用循环功能
    lhp_start_loop_once:function(params){if(this.is_edit==true){
        log_print("编辑模式下 无限循环监听功能循环次数设置为100:",this.data.var_name);
        params.count_max=1000
        };
        log_print(this.data.var_name,"run lhp_start_loop_once",params);
        lhp_start_loop_once(params)
    },
    accumulateParentOffsets:function (targetElement) {  
        let currentElement = targetElement;  
        let totalLeft = 0;  
        let totalTop = 0;  
      
        while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {  
            let computedStyle = window.getComputedStyle(currentElement);  
              
            if (computedStyle.position === 'relative') {  
                // 注意：offsetLeft 和 offsetTop 给出的是相对于最近的定位祖先的偏移  
                // 在这里，我们假设没有其他的定位祖先（或它们不影响我们的计算）  
                // 因为我们只关心 relative 定位的父元素  
                totalLeft += currentElement.offsetLeft;  
                totalTop += currentElement.offsetTop;  
            }  
      
            currentElement = currentElement.parentElement;  
        }  
      
        return { left: totalLeft, top: totalTop };  
    },
    get_x_y:function(event,ref_name){
    let x=event.clientX;
    let y=event.clientY;
    let res=this.accumulateParentOffsets(this.$refs[ref_name]);//累加所有relative 父dom的left和top
    return {x:res.left+x,y:res.top+y};
    },
    get_x_y2:function(event,ref_name){
    let x=event.clientX;
    let y=event.clientY;
    let res=this.accumulateParentOffsets(this.$refs[ref_name]);//累加所有relative 父dom的left和top
    return {x:x-res.left,y:y-res.top};
    },
    get_xys:function (targetElement) {  
        let currentElement = targetElement;  
        let totalLeft = 0;  
        let totalTop = 0;  
      
        while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {  
            let computedStyle = window.getComputedStyle(currentElement);  
              
            if (computedStyle.position === 'relative') {  
                // 注意：offsetLeft 和 offsetTop 给出的是相对于最近的定位祖先的偏移  
                // 在这里，我们假设没有其他的定位祖先（或它们不影响我们的计算）  
                // 因为我们只关心 relative 定位的父元素  
                totalLeft += currentElement.offsetLeft;  
                totalTop += currentElement.offsetTop;  
            }  
      
            currentElement = currentElement.parentElement;  
        }  
        let rect = targetElement.getBoundingClientRect();
    
        let width = rect.width;
        
        let height = rect.height;
        return { left: totalLeft, top: totalTop,width:width,height:height};  
    },
    init_con2:function(){
        let _this=this;
        // 将con2 容器的子组件 在初始化的时候将this传递给con2容器 start
        if(_this.con2_idx!='null'){
        try{
            // console.log("_this.con2_father_this",_this.con2_father_this)
        if(!_this.con2_father_this.fast_child){_this.con2_father_this.fast_child={}}
        let f=_this.con2_father_this.fast_child;
        if(!f[_this.con2_idx]){f[_this.con2_idx]={}}
        let f_lst=_this.deepcopy_data.__only_id.split("_");
        f[_this.con2_idx][f_lst[f_lst.length-1]]=_this;

        }catch{}
        // 将con2 容器的子组件 在初始化的时候传递给con2容器   end
    }
}
};
component2_watch_add_data={
'data.var_name':function(e){
    if(this.is_edit &&this.__edit_flag__==false){return;}
    lhp_check_obj(window,e,this.data);log_print(e,"已装载:",window[e])
    log_print("this.data.varname=",e)
    window[e+"_____x"]=this;

},
'data.body_data':{
handler(e, oldVal) {
    // console.log("e",e)
    let _this=this;
    try{
        if(!this.__body_data_md5){this.__body_data_md5={}}
            let l=e.length;
            let new_d=[];
            for(let i=0;i<l;i++){new_d.push(null)}
            let vue_obj=_this.tbody_obj.$refs.ref_obj;
            _this.tbody_obj.$refs.ref_obj.data.data=new_d;
            vue_obj.$nextTick(()=>{
            let new_dct={};
            for(let i=0;i<l;i++){
                let old_md5=_this.__body_data_md5[i];
                let new_md5=md5(JSON.stringify(e[i]));
                if(new_md5!=old_md5){
                    let body_keys=Object.keys(_this.data.__father_data);
                    let new_keys={};
                    for (let i=0;i<body_keys.length;i++){
                      let k_lst=body_keys[i].split("_");
                      new_keys[k_lst[k_lst.length-1]]=body_keys[i];
                    }
                    try{
                      let data=_this.data.body_data[i];
                    //   console.log("开始同步第",i,"条数据",new_keys,data);
                      for(let key in new_keys){
                        // console.log("lhp_deepcopy1(this.fast_child[i][key].data,data[new_keys[key]])",this.fast_child[i][key].data,data,key,data[12],data[new_keys[key]])
                        try{lhp_deepcopy1(_this.fast_child[i][key].data,data[key]);}catch (err){}
                        
                      }
                }catch{}
                new_dct[i]=new_md5;

            }
        }});

    }catch{}
},
deep: true, // 启用深度监听
immediate: false // 设置为 true 会在绑定时立即执行一次 handler
}
}
component2_mounted_start_data=`
let _this=this;
try{_this.data.return_this=function(){return _this}}catch{}
try{_this.data.__name=_this.$options.__name;}catch{}
try{_this.data._use_type=_this.$options._use_type;}catch{}

`

component2_created_start_data=`
let _this=this;
try{_this.init_con2();}catch{}
`
component2_created_end_data=``
component2_mounted_end_data=`
if (_this.var_name){
    _this.data.var_name=_this.var_name;
    window[_this.var_name]=_this.data;
    window[_this.var_name+"_____x"]=_this;

}


if(_this.deepcopy_data&&(window.component2_edit_flag==false)){lhp_deepcopy1(_this.deepcopy_data,{__style:{__edit_flag__:false} })}
try{if (_this.deepcopy_data){lhp_deepcopy1(_this.data,_this.deepcopy_data);}}//读取编辑状态下设定的参数
catch(error){log_print("######################",_this.deepcopy_data.var_name,"渲染出错:",error)}

`
component2_test_flag=false;
Vue.component2=function(temp_template_name,obj){
    let new_component2_data_add_data__=JSON.parse(JSON.stringify(component2_data_add_data__));
    let new_component2_props_add_data=JSON.parse(JSON.stringify(component2_props_add_data));
    let new_component2_methods_add_data={};lhp_deepcopy1(new_component2_methods_add_data,component2_methods_add_data);
    let new_component2_watch_add_data={};lhp_deepcopy1(new_component2_watch_add_data,component2_watch_add_data);
    if(component2_test_flag){log_print("加载模板:",temp_template_name)}
    //自定义属性初始化
    if (!obj.hasOwnProperty("watch_bind")){obj["watch_bind"] = {};}//监听后 将值绑定为方法名=>data.方法名  方法绑定对应函数
    if (!obj.hasOwnProperty("watch_init")){obj["watch_init"] = {};}//监听后 将值作为传参运行 对应函数
    if (!obj.hasOwnProperty("watch_regist")){obj["watch_regist"] = {};}//监听后 将值作为函数运行 用于注册配置相关信息
    if (!obj.hasOwnProperty("recv_callback_func")){obj["recv_callback_func"] = {};}//接收回调函数的 函数    '___xxx":function(calback_func){this.data.___xxxxx.push(callback_func)}
    if (!obj.hasOwnProperty("bind_recv_callback_func")){obj["bind_recv_callback_func"] = {};}//绑定 接收回调函数的 函数  '___ccc'
    if(component2_test_flag){log_print("自定义属性初始化 完成")}
    //默认属性初始化
    if (!obj.hasOwnProperty("props")){obj["props"] = {};} 
    if (!obj.hasOwnProperty("data")){obj["data"] = function(){return {}};} 
    if (!obj.hasOwnProperty("methods")){obj["methods"] = {};} 
    if (!obj.hasOwnProperty("watch")){obj["watch"] = {};} 
    if (!obj.hasOwnProperty("mounted")){obj["mounted"] = function(){};} 
    if (!obj.hasOwnProperty("created")){obj["created"] = function(){};} 
    if(component2_test_flag){log_print("默认属性初始化 完成")}
    //获取并删除自定义参数
    let watch_bind=obj.watch_bind;delete obj.watch_bind;  
    let watch_init=obj.watch_init;delete obj.watch_init;
    let watch_regist=obj.watch_regist;delete obj.watch_regist;
    let recv_callback_func=obj.recv_callback_func;delete obj.recv_callback_func;  
    let bind_recv_callback_func=obj.bind_recv_callback_func;delete obj.bind_recv_callback_func;  
    if(component2_test_flag){log_print("获取并删除自定义参数 完成")}
    //自定义属性初始处理
    //----------------------watch_bind
    for(let key in watch_bind){
        //设置data初始值为''
        new_component2_data_add_data__[key]="";
        //设置method
        let md_name=key+"_____bn";
        new_component2_methods_add_data[md_name]=watch_bind[key];
        //设置watch监听
        new_component2_watch_add_data['data.'+key]=function(e){log_print("eeeeeee",e);lhp_check_obj(this.data,e,this[md_name])}
    }
    //----------------------watch_init
    for(let key in watch_init){
        //设置data初始值为''
        new_component2_data_add_data__[key]="";
        //设置watch监听
        new_component2_watch_add_data['data.'+key]=watch_init[key];
    }
    //----------------------watch_regist
    for(let key in watch_regist){
        let watch_regist_obj=watch_regist[key];
        // log_print(this.data.var_name,'watch_regist_obj',watch_regist_obj)
        let regist_path=watch_regist_obj.regist_path;//注册路径
        let try_type=watch_regist_obj.type;//报错不删除对象
        let callback_name=watch_regist_obj.callback_name;//注册后获取到的注册对象
        let recv_data_name=watch_regist_obj.recv_data_name;//接收数据的属性名称  this.data[recv_data_name]
        let recv_func_check_ref=watch_regist_obj.recv_func_check_ref;//不为空 则会检查ref是否存在才会运行后续函数
        let recv_func=watch_regist_obj.recv_func;//后续函数
        let other_callback=watch_regist_obj.other_callback;
        let new_other_callback={};
        //后续函数绑定到 methods中
        if (recv_func!=null && recv_func!=undefined){new_component2_methods_add_data[key+'___recv_func']=recv_func;}
        
        let new_func=function(e){
            let _this=this;
            let watch_regist_set_this=_this;
            if((watch_regist_set_this['watch_regist_set_'+key+'_flag']!=true)&&(!(other_callback===undefined))){
                watch_regist_set_this['watch_regist_set_'+key+'_flag']=true;
                for(let key33 in other_callback){
                    watch_regist_set_this['watch_regist_set_'+key+'_bind_other_callback_'+key33]=other_callback[key33]
                    
                new_other_callback[key33]=function(...params){
                    watch_regist_set_this['watch_regist_set_'+key+'_bind_other_callback_'+key33](...params);
                }
                }
            }

            _this.lhp_start_loop_once({
                func:e,//注册函数 xxx.xxx
                params:{//注册参数
                    _this:_this,
                    other_callback:new_other_callback,//监听的其他数据
                    var_name:_this.data.var_name,
                    path:regist_path,//注册绑定的路径
                    type:try_type,//报错不删除对象
                    func:function(obj){
                        _this.data.test_flag=true;
                        try{if(_this.data.test_flag==true){log_print("【",_this.data.var_name,"】","传参数据2:",obj)}}catch{}
                        log_print("【",_this.data.var_name,"】","调用回调函数")
                        let path=obj.path;//更新数据的路径
                        let data_type=obj.data_type;
                        let data=obj.data
                        if(path==''){path=recv_data_name}else{path=recv_data_name+'.'+path}
                        try{if(_this.data.test_flag==true){log_print("【",_this.data.var_name,"】","更新数据和路径:",path,data)}}catch{}
                        //更新数据
                        try{
                            lhp_vue_set({data_type:data_type,_this:_this,path:path,data:data,before_idx:obj.before_idx});
                            try{if(_this.data.test_flag==true){log_print('更新完毕:',_this)}}catch{}
                            if (recv_func_check_ref!=''&&recv_func_check_ref!=null &&recv_func_check_ref!=undefined){
                                ttime3(recv_func_check_ref,_this[key+'___recv_func'])
                            }else if(recv_func!=null && recv_func!=undefined){
                                
          log_print("xczxczx start ---1")
                                _this[key+'___recv_func']()
                            
          log_print("xczxczx start ---2")}
                        }catch(error) {  
                            // 如果try块中的代码抛出了错误，控制将跳转到这里  
                            // error对象包含了错误的详细信息  
                            log_print("【",_this.data.var_name,"】","捕获到错误:", error.message); // 使用
                        }
                    },//数据更新后同步执行的函数
            },
                callback:function(get_data_func){//回调函数
                //主动获取注册路径的数据   get_data_func(now_data) 通过判断now_data的md5与配置对象当前存储的数据 来选择是否进行数据更新
                _this.data[callback_name]=get_data_func;
            }
            });

        }
        //设置data初始值为''
        new_component2_data_add_data__[key]="";
        //设置watch监听
        new_component2_watch_add_data['data.'+key]=new_func;
    }
    if(component2_test_flag){log_print("自定义属性初始处理 完成")}
    
    //----------------------recv_callback_func
    
    for(let key in recv_callback_func){
        //设置data初始值为''
        new_component2_data_add_data__[key]="";
        //设置method
        let md_name=key+"_____bn";
        new_component2_methods_add_data[md_name]=recv_callback_func[key];
        //设置watch监听
        new_component2_watch_add_data['data.'+key]=function(e){lhp_check_obj(this.data,e,this[md_name])}
    }
    //----------------------bind_recv_callback_func
    log_print(temp_template_name,"bind_recv_callback_func",bind_recv_callback_func)
    for(let key in bind_recv_callback_func){
        //设置data初始值为''
        new_component2_data_add_data__[key]="";
        //设置watch监听
        new_component2_watch_add_data['data.'+key]=bind_recv_callback_func[key];
    }
    //默认属性初始处理
    //----------------------props
    lhp_deepcopy1(obj['props'],new_component2_props_add_data)
    //----------------------data
    obj.data=component2_data_add_data(temp_template_name,obj.data,new_component2_data_add_data__);
    //----------------------methods
    lhp_deepcopy1(obj['methods'],new_component2_methods_add_data)
    //----------------------watch
    lhp_deepcopy1(obj['watch'],new_component2_watch_add_data)
    //----------------------mounted
    let mounted_str=null,start=null,end=null;
    mounted_str=obj['mounted'].toString();
    start=mounted_str.indexOf('{'),end=mounted_str.lastIndexOf('}'); 
    mounted_str=mounted_str.slice(start + 1, end);
    window.last_dom={
        component2_mounted_start_data:component2_mounted_start_data,
        mounted_str:mounted_str,
        component2_mounted_end_data:component2_mounted_end_data,

    }
    // console.log("1")
    // console.log(component2_mounted_start_data,mounted_str,component2_mounted_end_data)
    obj['mounted']=new Function(component2_mounted_start_data+'\n'+mounted_str+'\n'+component2_mounted_end_data);
    
    let created_str=null;
    created_str=obj['created'].toString();
    start=created_str.indexOf('{'),end=created_str.lastIndexOf('}'); 
    created_str=created_str.slice(start + 1, end);
    obj['created']=new Function(component2_created_start_data+'\n'+created_str+'\n'+component2_created_end_data);
    // console.log("2")
    if(component2_test_flag){log_print("默认属性初始处理 完成")}
    //----------------------其他
    obj._name=temp_template_name;//设置name
    obj.name=vue_temp_change_name(temp_template_name);//设置name
    if(component2_test_flag){log_print("其他处理 完成")}
    if(component2_test_flag){log_print("开始调用vue函数定义全局组件")}
    //调用vue函数定义全局组件
    // console.log(temp_template_name,obj.created)
    Vue.component(temp_template_name,obj);
}
Vue.component2('select2__', {  
  template: `
<el-dialog  
  :title="data.title"  
  :visible.sync="dialogVisible"  
  width="30%"  
  :before-close="handleClose">  
  <div>  
    <el-select style="width:40%"v-model="selectedOption1" placeholder="请选择">  
      <el-option  
        v-for="item in data.options1"  
        :key="item.value"  
        :label="item.label"  
        :value="item.value">  
      </el-option>  
    </el-select>  
    <div class="el-select"style="width:15%"><div style="display: grid;place-items: center;">=&gt;</div></div>
    <el-select style="width:40%" v-model="selectedOption2" placeholder="请选择">  
      <el-option  
        v-for="item in data.options2"  
        :key="item.value"  
        :label="item.label"  
        :value="item.value">  
      </el-option>  
    </el-select>  
  </div>  
  <span slot="footer" class="dialog-footer">  
    <el-button @click="dialogVisible = false">取 消</el-button>  
    <el-button type="primary" @click="submitForm">确 定</el-button>  
  </span>  
</el-dialog>  
`,  
data(){  

  return {  
      dialogVisible: true,
      selectedOption1: '',  
      selectedOption2: '',  
      textValue: '',  
      data:{
        title:'提示',
          options1: [  
          ],  
          options2: [  
          ]  ,
          callback:null,
      }
      
      
  }    

},
  methods: {  
      handleClose(done) {  
          this.$confirm('确认关闭？')  
            .then(_ => {  
              done();  
            })  
            .catch(_ => {});  
        },  
        check(){
          let fg1=0;let fg2=0;//标志
          let index1=0,index2=0;//index
          for(index1=0;index1<this.data.options1.length;index1++){
            if (this.data.options1[index1].value==this.selectedOption1){fg1=1;break}
          }
          if (fg1==0){return false}
          for(index2=0;index2<this.data.options2.length;index2++){
            if (this.data.options2[index2].value==this.selectedOption2){fg1=1;return {
              index1:index1,index2:index2
            }}
          }
          return false
        },
        submitForm() {  
          let res=this.check();
          if (res){
            if (this.data.callback){this.data.callback(
              {key1:this.selectedOption1,value1:this.data.options1[res.index1].label,
              key2:this.selectedOption2,value2:this.data.options2[res.index2].label,
            })}
            // 在这里可以添加更多逻辑，比如发送数据到服务器  
            this.dialogVisible = false; // 关闭对话框  
          }
          else{
            this.$confirm('参数为空，请重新输入或者取消。')  
            .then(_ => {  
            })  
            .catch(_ => {});  
          }
        }  
  },  
} 
);



window.select2__=function(info={
"title":"1->2",
  "select1":{1:"params1",2:"params2"},"select2":{1:"recv_params1",2:"recv_params2",3:"recv_params3"},
  callback:function(params){console.log("select:",params);
}
}){
      let option1=[];
      let option2=[];
      for (let key in info.select1){
          option1.push({value: key, label: info.select1[key]})
      }
      for (let key in info.select2){
          option2.push({value: key, label: info.select2[key]})
      }
  const DialogConstructor = Vue.extend({  
      template: '<select2__ :deepcopy_data="val"></select2__>',  
      data() {  
          return{
              val:{
                  options1:option1,
                  options2:option2,
                  callback:info.callback,
              }
          }
      },  
      methods: {  
          onConfirm() {  
              // 对话框确认后的逻辑  
              this.$destroy(); // 销毁Vue实例  
              this.$el.remove(); // 从DOM中移除元素  
          }  
      },  
      mounted() {  
          document.body.appendChild(this.$el); // 将对话框挂载到body下  
      }  
  });  

  // 创建并挂载Vue实例  
  new DialogConstructor().$mount();  
}
Vue.component2('select3_____menu_default_item', {  
    template: `
<div class="select3_____sub_menu_item" @click="click">
    {{data.text}}
</div>
  `,  
  data(){  
  
    return {  
        data:{
            __key__:"1",
            text:"line",
            callback:null,
        }
        
        
    }    
  
  },
    methods: {  
        click(){
            try{
                this.data.callback(this.data.__key__)
            }catch{}
          },
    },  
    
  mounted:function(){
    _this.data.callback=_this.deepcopy_data.callback;
    }
  } 
  );
  
  

Vue.component2('select3_____menu', {  
    template: `
        <div class="select3_____sub_menu" ref="body"  v-show='show_flag'>
            
        </div>
  `,
  data(){
    return{
        show_flag:false,
        data:{
            menu_data:[],
            menu_item_vue_name:"select3_____menu_default_item",
            __menu_data:[],
        }
    }
  },
  watch:{
  },
  methods:{
    remove_dom:function(){
            // 获取当前元素的所有子元素
            let children = Array.from(this.$refs.body.children);
            // Array.from(select3_____vue.$refs.ref_obj.$refs.body.children)
            for(let i=0;i<children.length;i++){
                if (children[i].tagName.toLowerCase() !== 'style'){
                    this.$refs.body.removeChild(children[i]);
                }
            }
            this.data.__menu_data=[];
    },
    create_dom:function(obj){
        this.create_time=Date.now();
        // console.log("##########obj",obj)
        this.init_style();
        this.$refs.body.style.left=obj.x+'px';
        this.$refs.body.style.top=obj.y+'px';
        // console.log("##########this.show_flag1",this.show_flag)
        this.show_flag=true;
        this.data.menu_data=obj.menu_data;
        this.data.menu_item_vue_name=obj.vue_name;
        let _this=this;
        this.data.callback=async function(xxx){
            _this.show_flag=false;
            try{
                await obj.callback(xxx);}
            catch{
                obj.callback(xxx);
            }
        }
        this.remove_dom();
        for(let __key__=0;__key__<this.data.menu_data.length;__key__++){
            let new_dom=document.createElement(this.data.menu_item_vue_name);
            //设置dom属性 ref值为ref_obj
            new_dom.setAttribute('ref','ref_obj');
            new_dom.setAttribute(':deepcopy_data','deepcopy_data');
            let deepcopy_data=JSON.parse(JSON.stringify(this.data.menu_data[__key__]));
            deepcopy_data['__key__']=__key__;
            deepcopy_data['callback']=_this.data.callback;
            //设置vue
            let vue_dct={'el':new_dom,data:{deepcopy_data:deepcopy_data}};
            // 将这个 div 添加到 document.documentElement（即 <html> 元素）  
            this.$refs.body.appendChild(new_dom);
            //渲染vue组件
            this.data.__menu_data.push(new Vue(vue_dct));
        }
        
        // console.log("##########this.show_flag2",this.show_flag)
    },
    init_style:function(){
        try{
            // 判断是否找到了style标签
            if (!this.$refs.body.querySelector("style")) {
            // 不存在style标签时执行的操作（可选）
            let new_dom=document.createElement("style");
            new_dom.innerHTML=`
                    .select3_____sub_menu {
                        position: absolute;
                        background-color: #212121;
                        /* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3); */
                        z-index: 1000;
                        padding:5px;
                        border: 1px solid #2b2b2b;
                        border-radius: 8px;
                        width:100px;
                    }
                    .select3_____sub_menu_item {
                        color:rgba(231, 231, 231, 0.6);
                        white-space: nowrap;border-radius: 4px;
                    
                        -webkit-user-select: none;
                        display: flex;
                        justify-content: center; 
                        align-items: center;   
                        cursor: pointer;
                    }
                    .select3_____sub_menu_item:hover{    outline: 1px solid #0078d4;
                        background-color: rgb(4, 57, 94);
                        color:rgba(231, 231, 231, 0.6);
                    }`;
          this.$refs.body.appendChild(new_dom);

        }
        }catch (err){console.log("err:",err)}
    }
  },
  
  mounted:function(){
  ttime2(function(){try{return this.$refs.body}catch{return 0}},this.init_style);
  _this.data.refresh=function(){_this.refresh='2'?'1':'2'};
  _this.data.x=_this.deepcopy_data.x;
  _this.data.y=_this.deepcopy_data.y;
  }
  
  })











  
  window.select3_____dom=null;//表示菜单的dom
  window.select3_____vue=null;//表示菜单的dom
  window.select3__=function(obj){
  
  let x=null;
  let y=null;
  if(obj.event){
    obj.x=obj.event.clientX;
    obj.y=obj.event.clientY;
  }
  if(obj.add_xy){
    obj.x=obj.x+obj.add_xy.x;
    obj.y=obj.y+obj.add_xy.y;
  }
  let deepcopy_data={}
  //如果菜单不存在则创建一个菜单
  if(!select3_____dom){
  let new_dom=document.createElement('select3_____menu');
  //设置dom属性 ref值为ref_obj
  new_dom.setAttribute('ref','ref_obj');
  new_dom.setAttribute(':deepcopy_data','deepcopy_data');
  //设置vue
  let vue_dct={'el':new_dom,data:{true:true,false:false,null:null,deepcopy_data:deepcopy_data}};
  // 将这个 div 添加到 document.documentElement（即 <html> 元素）  
  document.documentElement.appendChild(new_dom);
  //渲染vue组件
  window.select3_____vue=new Vue(vue_dct);
  window.select3_____dom=new_dom;
  
  document.addEventListener('click', function(event) {
    // Check if the clicked element is not doma and not a descendant of doma
    if (!window.select3_____vue.$refs.ref_obj.$el.contains(event.target)) {
    //   console.log("隐藏")
        // console.log("鼠标点击其他位置 判断是否隐藏")
        let t=Date.now();
        if (window.select3_____vue.$refs.ref_obj.create_time+500<t){
            // console.log("超过0.5秒 隐藏")
            window.select3_____vue.$refs.ref_obj.show_flag=false;
        }else{
            // console.log("没有超过0.5秒",window.select3_____vue.$refs.ref_obj.create_time,t)
        }
    }
  });
  }else{
    select3_____vue.$refs.ref_obj.show_flag=true;
    
    window.select3_____vue.$refs.ref_obj.create_dom(obj);
  }
  
  
  }

  window.select3__({
    x:333,y:444,menu_data:[{"text":'ss'},{"text":'yy'},],vue_name:"select3_____menu_default_item",callback:function(select){console.log("当前选择:",select)}
  })

